From e9827c8b2525fd16ffc1fee9263c54f5d737e97c Mon Sep 17 00:00:00 2001 From: Bai Date: Tue, 7 Apr 2020 12:26:47 +0800 Subject: [PATCH] =?UTF-8?q?[Update]=20=E6=B7=BB=E5=8A=A0=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E6=A0=A1=E9=AA=8CAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/api/session.py | 46 +++++++++++++++++++++++++--- apps/terminal/models.py | 8 +++-- apps/terminal/serializers/session.py | 7 ++++- apps/terminal/urls/api_urls.py | 1 + 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/apps/terminal/api/session.py b/apps/terminal/api/session.py index b036f376c..4653e673d 100644 --- a/apps/terminal/api/session.py +++ b/apps/terminal/api/session.py @@ -1,22 +1,27 @@ # -*- coding: utf-8 -*- # +from django.utils.translation import ugettext as _ from django.shortcuts import get_object_or_404, reverse from django.core.files.storage import default_storage -from rest_framework import viewsets +from rest_framework import viewsets, views from rest_framework.response import Response -from common.utils import is_uuid, get_logger +from common.utils import is_uuid, get_logger, get_object_or_none from common.mixins.api import AsyncApiMixin -from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor +from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser from common.drf.filters import DatetimeRangeFilter from orgs.mixins.api import OrgBulkModelViewSet +from orgs.utils import tmp_to_root_org, tmp_to_org +from users.models import User from ..utils import find_session_replay_local, download_session_replay from ..hands import SystemUser from ..models import Session from .. import serializers -__all__ = ['SessionViewSet', 'SessionReplayViewSet',] +__all__ = [ + 'SessionViewSet', 'SessionReplayViewSet', 'SessionJoinValidateAPI' +] logger = get_logger(__name__) @@ -117,3 +122,36 @@ class SessionReplayViewSet(AsyncApiMixin, viewsets.ViewSet): return Response({"error": url}) data = self.get_replay_data(session, url) return Response(data) + + +class SessionJoinValidateAPI(views.APIView): + permission_classes = (IsAppUser, ) + serializer_class = serializers.SessionJoinValidateSerializer + + def post(self, request, *args, **kwargs): + serializer = self.serializer_class(data=request.data) + if not serializer.is_valid(): + msg = str(serializer.errors) + return Response({'ok': False, 'msg': msg}, status=401) + user_id = serializer.validated_data['user_id'] + session_id = serializer.validated_data['session_id'] + + with tmp_to_root_org(): + session = get_object_or_none(Session, pk=session_id) + if not session: + msg = _('Session does not exist: {}'.format(session_id)) + return Response({'ok': False, 'msg': msg}, status=401) + if not session.can_join(): + msg = _('Session is finished or the protocol not supported') + return Response({'ok': False, 'msg': msg}, status=401) + + user = get_object_or_none(User, pk=user_id) + 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 not user.admin_or_audit_orgs: + msg = _('User does not have permission') + return Response({'ok': False, 'msg': msg}, status=401) + + return Response({'ok': True, 'msg': ''}, status=200) diff --git a/apps/terminal/models.py b/apps/terminal/models.py index 08014a87d..3dd34de86 100644 --- a/apps/terminal/models.py +++ b/apps/terminal/models.py @@ -244,9 +244,11 @@ class Session(OrgModelMixin): return False def can_join(self): - if self.protocol in ['ssh', 'telnet', 'mysql']: - return True - return False + if self.is_finished: + return False + if self.protocol not in ['ssh', 'telnet', 'mysql']: + return False + return True def save_to_storage(self, f): local_path = self.get_local_path() diff --git a/apps/terminal/serializers/session.py b/apps/terminal/serializers/session.py index 85d9241a7..bed6525b5 100644 --- a/apps/terminal/serializers/session.py +++ b/apps/terminal/serializers/session.py @@ -6,7 +6,7 @@ from ..models import Session __all__ = [ 'SessionSerializer', 'SessionDisplaySerializer', - 'ReplaySerializer', + 'ReplaySerializer', 'SessionJoinValidateSerializer', ] @@ -35,3 +35,8 @@ class SessionDisplaySerializer(SessionSerializer): class ReplaySerializer(serializers.Serializer): file = serializers.FileField(allow_empty_file=True) + + +class SessionJoinValidateSerializer(serializers.Serializer): + user_id = serializers.UUIDField() + session_id = serializers.UUIDField() diff --git a/apps/terminal/urls/api_urls.py b/apps/terminal/urls/api_urls.py index 8c19fa685..1b2eb156c 100644 --- a/apps/terminal/urls/api_urls.py +++ b/apps/terminal/urls/api_urls.py @@ -22,6 +22,7 @@ router.register(r'replay-storages', api.ReplayStorageViewSet, 'replay-storage') router.register(r'command-storages', api.CommandStorageViewSet, 'command-storage') urlpatterns = [ + path('sessions/join/validate/', api.SessionJoinValidateAPI.as_view(), name='join-session'), path('sessions//replay/', api.SessionReplayViewSet.as_view({'get': 'retrieve', 'post': 'create'}), name='session-replay'),