diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index a86ce8b8d..6c65ec20f 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -10,6 +10,7 @@ from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied +from rest_framework import serializers from common.utils import get_logger, random_string from common.drf.api import SerializerMixin2 @@ -120,7 +121,8 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView 'autoreconnection enabled:i': '1', 'bookmarktype:i': '3', 'use redirection server name:i': '0', - 'smart sizing:i': '0' + 'smart sizing:i': '0', + # 'domain:s': '' # 'alternate shell:s:': '||MySQLWorkbench', # 'remoteapplicationname:s': 'Firefox', # 'remoteapplicationcmdline:s': '', @@ -140,12 +142,13 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView user = request.user token = self.create_token(user, asset, application, system_user) - # Todo: 上线后地址是 JumpServerAddr:3389 address = settings.TERMINAL_RDP_ADDR if not address or address == 'localhost:3389': address = request.get_host().split(':')[0] + ':3389' options['full address:s'] = address options['username:s'] = '{}|{}'.format(user.username, token) + if system_user.ad_domain: + options['domain:s'] = system_user.ad_domain if width and height: options['desktopwidth:i'] = width options['desktopheight:i'] = height @@ -161,10 +164,9 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView return response @staticmethod - def _get_application_secret_detail(value): + def _get_application_secret_detail(application): from applications.models import Application from perms.models import Action - application = get_object_or_404(Application, id=value.get('application')) gateway = None if not application.category_remote_app: @@ -190,15 +192,15 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView } @staticmethod - def _get_asset_secret_detail(value, user, system_user): - from assets.models import Asset + def _get_asset_secret_detail(asset, user, system_user): from perms.utils.asset import get_asset_system_user_ids_with_actions_by_user - asset = get_object_or_404(Asset, id=value.get('asset')) systemuserid_actions_mapper = get_asset_system_user_ids_with_actions_by_user(user, asset) actions = systemuserid_actions_mapper.get(system_user.id, []) + gateway = None if asset and asset.domain and asset.domain.has_gateway(): gateway = asset.domain.random_gateway() + return { 'asset': asset, 'application': None, @@ -207,32 +209,49 @@ class UserConnectionTokenViewSet(RootOrgViewMixin, SerializerMixin2, GenericView 'actions': actions, } - @action(methods=['POST'], detail=False, permission_classes=[IsSuperUserOrAppUser], url_path='secret-info/detail') - def get_secret_detail(self, request, *args, **kwargs): + def valid_token(self, token): from users.models import User - from assets.models import SystemUser + from assets.models import SystemUser, Asset + from applications.models import Application - token = request.data.get('token', '') key = self.CACHE_KEY_PREFIX.format(token) value = cache.get(key, None) if not value: - return Response(status=404) - user = get_object_or_404(User, id=value.get('user')) - system_user = get_object_or_404(SystemUser, id=value.get('system_user')) - data = dict(user=user, system_user=system_user) + raise serializers.ValidationError('Token not found') + user = get_object_or_404(User, id=value.get('user')) + if user.is_valid: + raise serializers.ValidationError("User not valid, disabled or expired") + + system_user = get_object_or_404(SystemUser, id=value.get('system_user')) + if system_user.ad_domain: + system_user.username = '{0.username}@{0.ad_domain}'.format(system_user) + + asset = None + app = None if value.get('type') == 'asset': - asset_detail = self._get_asset_secret_detail(value, user=user, system_user=system_user) - asset = asset_detail.get('asset') - if asset: - system_user.load_asset_more_auth(asset.id, user.username, user.id) + asset = get_object_or_404(Asset, id=value.get('asset')) + else: + app = get_object_or_404(Application, id=value.get('application')) + + if asset and not asset.is_active: + raise serializers.ValidationError("Asset disabled") + return value, user, system_user, asset, app + + @action(methods=['POST'], detail=False, permission_classes=[IsSuperUserOrAppUser], url_path='secret-info/detail') + def get_secret_detail(self, request, *args, **kwargs): + token = request.data.get('token', '') + value, user, system_user, asset, app = self.valid_token(token) + + data = dict(user=user, system_user=system_user) + if asset: + asset_detail = self._get_asset_secret_detail(asset, user=user, system_user=system_user) + system_user.load_asset_more_auth(asset.id, user.username, user.id) data['type'] = 'asset' data.update(asset_detail) else: - app_detail = self._get_application_secret_detail(value) - app = app_detail.get("application") - if app: - system_user.load_app_more_auth(app.id, user.id) + app_detail = self._get_application_secret_detail(app) + system_user.load_app_more_auth(app.id, user.id) data['type'] = 'application' data.update(app_detail)