pref: 添加 applet 创建 api

This commit is contained in:
ibuler
2022-10-25 12:57:34 +08:00
parent 1372d6322d
commit 5606082ca3
24 changed files with 322 additions and 86 deletions

View File

@@ -1,10 +1,5 @@
# -*- coding: utf-8 -*-
#
from .terminal import *
from .session import *
from .command import *
from .task import *
from .storage import *
from .status import *
from .sharing import *
from .endpoint import *
from .component import *
from .applet import *

View File

@@ -0,0 +1,2 @@
from .applet import *
from .host import *

View File

@@ -0,0 +1,71 @@
import os.path
import shutil
import zipfile
import yaml
from django.core.files.storage import default_storage
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from terminal import serializers, models
from terminal.serializers import AppletUploadSerializer
class AppletViewSet(viewsets.ModelViewSet):
queryset = models.Applet.objects.all()
serializer_class = serializers.AppletSerializer
rbac_perms = {
'upload': 'terminal.add_applet',
}
@action(detail=False, methods=['post'], serializer_class=AppletUploadSerializer)
def upload(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
file = serializer.validated_data['file']
save_to = 'applets/{}'.format(file.name + '.tmp.zip')
if default_storage.exists(save_to):
default_storage.delete(save_to)
rel_path = default_storage.save(save_to, file)
path = default_storage.path(rel_path)
extract_to = default_storage.path('applets/{}.tmp'.format(file.name))
if os.path.exists(extract_to):
shutil.rmtree(extract_to)
update = request.query_params.get('update')
with zipfile.ZipFile(path) as zp:
if zp.testzip() is not None:
return Response({'msg': 'Invalid Zip file'}, status=400)
zp.extractall(extract_to)
tmp_dir = os.path.join(extract_to, file.name.replace('.zip', ''))
files = ['manifest.yml', 'icon.png', 'i18n.yml']
for name in files:
path = os.path.join(tmp_dir, name)
if not os.path.exists(path):
return Response({'error': 'Missing file: {}'.format(path)}, status=400)
with open(os.path.join(tmp_dir, 'manifest.yml')) as f:
manifest = yaml.safe_load(f)
name = manifest.get('name', '')
instance = models.Applet.objects.filter(name=name).first()
if instance and not update:
return Response({'error': 'Applet already exists: {}'.format(name)}, status=400)
serializer = serializers.AppletSerializer(data=manifest, instance=instance)
serializer.is_valid(raise_exception=True)
save_to = default_storage.path('applets/{}'.format(name))
if os.path.exists(save_to):
shutil.rmtree(save_to)
shutil.move(tmp_dir, save_to)
serializer.save()
return Response(serializer.data, status=201)
class AppletPublicationViewSet(viewsets.ModelViewSet):
queryset = models.AppletPublication.objects.all()
serializer_class = serializers.AppletPublicationSerializer

View File

@@ -0,0 +1,16 @@
from rest_framework import viewsets
from terminal import serializers, models
__all__ = ['AppletHostViewSet', 'AppletHostDeploymentViewSet']
class AppletHostViewSet(viewsets.ModelViewSet):
queryset = models.AppletHost.objects.all()
serializer_class = serializers.AppletHostSerializer
class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
queryset = models.AppletHostDeployment.objects.all()
serializer_class = serializers.AppletHostDeploymentSerializer

View File

@@ -0,0 +1,4 @@
from .terminal import *
from .storage import *
from .status import *
from .endpoint import *

View File

@@ -2,15 +2,15 @@ from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status
from rest_framework.request import Request
from common.drf.api import JMSBulkModelViewSet
from common.permissions import IsValidUserOrConnectionToken
from django.utils.translation import ugettext_lazy as _
from django.shortcuts import get_object_or_404
from assets.models import Asset
from orgs.utils import tmp_to_root_org
from terminal.models import Session
from ..models import Endpoint, EndpointRule
from .. import serializers
from common.permissions import IsValidUserOrConnectionToken
from terminal.models import Session, Endpoint, EndpointRule
from terminal import serializers
__all__ = ['EndpointViewSet', 'EndpointRuleViewSet']

View File

@@ -9,9 +9,9 @@ from rest_framework import viewsets, generics
from rest_framework.views import Response
from rest_framework import status
from ..models import Terminal, Status, Session
from .. import serializers
from ..utils import TypedComponentsStatusMetricsUtil
from terminal.models import Terminal, Status, Session
from terminal import serializers
from terminal.utils import TypedComponentsStatusMetricsUtil
logger = logging.getLogger(__file__)

View File

@@ -11,8 +11,8 @@ from django_filters import utils
from terminal import const
from common.const.http import GET
from terminal.filters import CommandStorageFilter, CommandFilter, CommandFilterForStorageTree
from ..models import CommandStorage, ReplayStorage
from ..serializers import CommandStorageSerializer, ReplayStorageSerializer
from terminal.models import CommandStorage, ReplayStorage
from terminal.serializers import CommandStorageSerializer, ReplayStorageSerializer
__all__ = [
'CommandStorageViewSet', 'CommandStorageTestConnectiveApi',

View File

@@ -14,9 +14,9 @@ from common.exceptions import JMSException
from common.drf.api import JMSBulkModelViewSet
from common.utils import get_object_or_none, get_request_ip
from common.permissions import WithBootstrapToken
from ..models import Terminal
from .. import serializers
from .. import exceptions
from terminal.models import Terminal
from terminal import serializers
from terminal import exceptions
__all__ = [
'TerminalViewSet', 'TerminalConfig',

View File

@@ -0,0 +1,4 @@
from .session import *
from .sharing import *
from .command import *
from .task import *

View File

@@ -13,11 +13,11 @@ from common.drf.api import JMSBulkModelViewSet
from common.utils import get_logger
from terminal.backends.command.serializers import InsecureCommandAlertSerializer
from terminal.exceptions import StorageInvalid
from ..backends import (
from terminal.backends import (
get_command_storage, get_multi_command_storage,
SessionCommandSerializer,
)
from ..notifications import CommandAlertMessage
from terminal.notifications import CommandAlertMessage
logger = get_logger(__name__)
__all__ = ['CommandViewSet', 'InsecureCommandAlertAPI']

View File

@@ -24,15 +24,16 @@ 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
from terminal.utils import is_session_approver
from terminal.utils import (
find_session_replay_local, download_session_replay,
is_session_approver, get_session_replay_url
)
from terminal.models import Session
from terminal import serializers
__all__ = [
'SessionViewSet', 'SessionReplayViewSet', 'SessionJoinValidateAPI',
'MySessionAPIView',
'SessionViewSet', 'SessionReplayViewSet',
'SessionJoinValidateAPI', 'MySessionAPIView',
]
logger = get_logger(__name__)
@@ -93,7 +94,7 @@ class SessionViewSet(OrgBulkModelViewSet):
url_name='replay-download')
def download(self, request, *args, **kwargs):
session = self.get_object()
local_path, url = utils.get_session_replay_url(session)
local_path, url = get_session_replay_url(session)
if local_path is None:
return Response({"error": url}, status=404)
file = self.prepare_offline_file(session, local_path)

View File

@@ -5,9 +5,8 @@ from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from common.const.http import PATCH
from common.permissions import IsValidUser
from orgs.mixins.api import OrgModelViewSet
from .. import serializers, models
from terminal import serializers, models
__all__ = ['SessionSharingViewSet', 'SessionJoinRecordsViewSet']

View File

@@ -7,10 +7,10 @@ from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from common.utils import get_object_or_none
from ..models import Session, Task
from .. import serializers
from terminal.utils import is_session_approver
from orgs.utils import tmp_to_root_org
from terminal.models import Session, Task
from terminal import serializers
from terminal.utils import is_session_approver
__all__ = ['TaskViewSet', 'KillSessionAPI', 'KillSessionForTicketAPI']
logger = logging.getLogger(__file__)