jumpserver/apps/terminal/api/component/terminal.py

108 lines
3.7 KiB
Python

# -*- coding: utf-8 -*-
#
import logging
from django.conf import settings
from django.db.models import Q
from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework as filters
from rest_framework import generics
from rest_framework import status
from rest_framework.views import APIView, Response
from common.api import JMSBulkModelViewSet
from common.drf.filters import BaseFilterSet
from common.exceptions import JMSException
from common.permissions import WithBootstrapToken, IsServiceAccount
from jumpserver.conf import ConfigCrypto
from terminal import serializers
from terminal.models import Terminal
__all__ = [
'TerminalViewSet', 'TerminalConfig',
'TerminalRegistrationApi', 'EncryptedTerminalConfig'
]
logger = logging.getLogger(__file__)
class TerminalFilterSet(BaseFilterSet):
name = filters.CharFilter(field_name='name', lookup_expr='icontains')
remote_addr = filters.CharFilter(field_name='remote_addr', lookup_expr='icontains')
class Meta:
model = Terminal
fields = ['name', 'remote_addr', 'type']
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
search = self.request.query_params.get('search')
if not search:
return queryset
q = Q(name__icontains=search) | Q(remote_addr__icontains=search)
queryset = queryset.filter(q)
return queryset
class TerminalViewSet(JMSBulkModelViewSet):
queryset = Terminal.objects.filter(is_deleted=False)
serializer_class = serializers.TerminalSerializer
filterset_class = TerminalFilterSet
custom_filter_fields = ['load']
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
if instance.get_online_session_count() > 0:
raise JMSException(
code='have_online_session',
detail=_('Have online sessions')
)
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
s = self.request.query_params.get('load')
if not s:
return queryset
filtered_queryset_id = [str(q.id) for q in queryset if q.load == s]
queryset = queryset.filter(id__in=filtered_queryset_id)
return queryset
class TerminalConfig(APIView):
rbac_perms = {
'GET': 'terminal.view_terminalconfig'
}
def get(self, request):
config = request.user.terminal.config
return Response(config, status=200)
class TerminalRegistrationApi(generics.CreateAPIView):
serializer_class = serializers.TerminalRegistrationSerializer
permission_classes = [WithBootstrapToken]
http_method_names = ['post']
def create(self, request, *args, **kwargs):
if not settings.SECURITY_SERVICE_ACCOUNT_REGISTRATION:
data = {"error": "service account registration disabled"}
return Response(data=data, status=status.HTTP_400_BAD_REQUEST)
return super().create(request, *args, **kwargs)
class EncryptedTerminalConfig(generics.CreateAPIView):
serializer_class = serializers.EncryptedConfigSerializer
permission_classes = [IsServiceAccount]
http_method_names = ['post']
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
encrypt_key = serializer.validated_data['secret_encrypt_key']
encrypted_value = serializer.validated_data['encrypted_value']
config_crypto = ConfigCrypto(encrypt_key)
value = config_crypto.decrypt(encrypted_value)
return Response(data={'value': value}, status=200)