From c0de27ff7a3a4c6fd25bb371d05d98538c7d5756 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 12 Oct 2023 18:11:51 +0800 Subject: [PATCH 1/5] =?UTF-8?q?perf:=20=E8=B5=84=E4=BA=A7=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=9B=B4=E6=96=B0=E5=B9=B3=E5=8F=B0=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=EF=BC=8C=E6=A0=B9=E6=8D=AE=E5=B9=B3=E5=8F=B0=E7=BA=A6=E6=9D=9F?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE=E8=87=AA=E5=8A=A8=E7=94=9F=E6=95=88=20(#1181?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/accounts/api/account/template.py | 2 +- apps/assets/api/asset/asset.py | 39 ++++++++++++++++++++++++- apps/assets/serializers/asset/common.py | 27 +++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/apps/accounts/api/account/template.py b/apps/accounts/api/account/template.py index 4493cb227..22d9508a7 100644 --- a/apps/accounts/api/account/template.py +++ b/apps/accounts/api/account/template.py @@ -46,7 +46,7 @@ class AccountTemplateViewSet(OrgBulkModelViewSet): } rbac_perms = { 'su_from_account_templates': 'accounts.view_accounttemplate', - 'sync_related_accounts': 'accounts.change_accounttemplate', + 'sync_related_accounts': 'accounts.change_account', } @action(methods=['get'], detail=False, url_path='su-from-account-templates') diff --git a/apps/assets/api/asset/asset.py b/apps/assets/api/asset/asset.py index f1573629e..4b36b4bbe 100644 --- a/apps/assets/api/asset/asset.py +++ b/apps/assets/api/asset/asset.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- # +from collections import defaultdict + import django_filters from django.db.models import Q from django.shortcuts import get_object_or_404 from django.utils.translation import gettext as _ +from rest_framework import status from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.status import HTTP_200_OK @@ -12,7 +15,7 @@ from accounts.tasks import push_accounts_to_assets_task, verify_accounts_connect from assets import serializers from assets.exceptions import NotSupportedTemporarilyError from assets.filters import IpInFilterBackend, LabelFilterBackend, NodeFilterBackend -from assets.models import Asset, Gateway, Platform +from assets.models import Asset, Gateway, Platform, Protocol from assets.tasks import test_assets_connectivity_manual, update_assets_hardware_info_manual from common.api import SuggestionMixin from common.drf.filters import BaseFilterSet, AttrRulesFilterBackend @@ -115,6 +118,7 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet): ("gateways", "assets.view_gateway"), ("spec_info", "assets.view_asset"), ("gathered_info", "assets.view_asset"), + ("sync_platform_protocols", "assets.change_asset"), ) extra_filter_backends = [ LabelFilterBackend, IpInFilterBackend, @@ -152,6 +156,39 @@ class AssetViewSet(SuggestionMixin, NodeFilterMixin, OrgBulkModelViewSet): gateways = asset.domain.gateways return self.get_paginated_response_from_queryset(gateways) + @action(methods=['post'], detail=False, url_path='sync-platform-protocols') + def sync_platform_protocols(self, request, *args, **kwargs): + platform_id = request.data.get('platform_id') + platform = get_object_or_404(Platform, pk=platform_id) + assets = platform.assets.all() + + platform_protocols = { + p['name']: p['port'] + for p in platform.protocols.values('name', 'port') + } + asset_protocols_map = defaultdict(set) + protocols = assets.prefetch_related('protocols').values_list( + 'id', 'protocols__name' + ) + for asset_id, protocol in protocols: + asset_id = str(asset_id) + asset_protocols_map[asset_id].add(protocol) + objs = [] + for asset_id, protocols in asset_protocols_map.items(): + protocol_names = set(platform_protocols) - protocols + if not protocol_names: + continue + for name in protocol_names: + objs.append( + Protocol( + name=name, + port=platform_protocols[name], + asset_id=asset_id, + ) + ) + Protocol.objects.bulk_create(objs) + return Response(status=status.HTTP_200_OK) + def create(self, request, *args, **kwargs): if request.path.find('/api/v1/assets/assets/') > -1: error = _('Cannot create asset directly, you should create a host or other') diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index ea2be442c..6d73287ee 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -298,10 +298,37 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali self.perform_nodes_display_create(instance, nodes_display) return instance + @staticmethod + def sync_platform_protocols(instance, old_platform): + platform = instance.platform + + if str(old_platform.id) == str(instance.platform_id): + return + + platform_protocols = { + p['name']: p['port'] + for p in platform.protocols.values('name', 'port') + } + + protocols = set(instance.protocols.values_list('name', flat=True)) + protocol_names = set(platform_protocols) - protocols + objs = [] + for name in protocol_names: + objs.append( + Protocol( + name=name, + port=platform_protocols[name], + asset_id=instance.id, + ) + ) + Protocol.objects.bulk_create(objs) + @atomic def update(self, instance, validated_data): + old_platform = instance.platform nodes_display = validated_data.pop('nodes_display', '') instance = super().update(instance, validated_data) + self.sync_platform_protocols(instance, old_platform) self.perform_nodes_display_create(instance, nodes_display) return instance From e1278360afec5c007cfab2814ffa151c50f01b80 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 12 Oct 2023 19:46:04 +0800 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E8=B5=84=E4=BA=A7=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=20(#11824)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/assets/serializers/asset/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/serializers/asset/common.py b/apps/assets/serializers/asset/common.py index 6d73287ee..78f691237 100644 --- a/apps/assets/serializers/asset/common.py +++ b/apps/assets/serializers/asset/common.py @@ -159,7 +159,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer, WritableNestedModelSeriali return if isinstance(self.initial_data, list): return - accounts = self.initial_data.get('accounts', None) + accounts = self.initial_data.pop('accounts', None) self._accounts = accounts def _get_protocols_required_default(self): From 58fd578ddd1230f48fe1574e510723cecc7c8d54 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 12 Oct 2023 20:04:28 +0800 Subject: [PATCH 3/5] =?UTF-8?q?perf:=20=E8=B5=84=E4=BA=A7=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=8F=90=E7=A4=BA=E6=B7=BB=E5=8A=A0=E8=B4=A6=E5=8F=B7?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=20(#11826)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/acls/notifications.py | 4 +++- apps/acls/templates/acls/asset_login_reminder.html | 1 + apps/authentication/api/connection_token.py | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/acls/notifications.py b/apps/acls/notifications.py index 5d3c59e13..cf19b7a51 100644 --- a/apps/acls/notifications.py +++ b/apps/acls/notifications.py @@ -41,9 +41,10 @@ class UserLoginReminderMsg(UserMessage): class AssetLoginReminderMsg(UserMessage): subject = _('Asset login reminder') - def __init__(self, user, asset: Asset, login_user: User): + def __init__(self, user, asset: Asset, login_user: User, account_username): self.asset = asset self.login_user = login_user + self.account_username = account_username super().__init__(user) def get_html_msg(self) -> dict: @@ -51,6 +52,7 @@ class AssetLoginReminderMsg(UserMessage): 'recipient': self.user.username, 'username': self.login_user.username, 'asset': str(self.asset), + 'account': self.account_username, } message = render_to_string('acls/asset_login_reminder.html', context) diff --git a/apps/acls/templates/acls/asset_login_reminder.html b/apps/acls/templates/acls/asset_login_reminder.html index 9a30cda49..8d63a2ff6 100644 --- a/apps/acls/templates/acls/asset_login_reminder.html +++ b/apps/acls/templates/acls/asset_login_reminder.html @@ -4,6 +4,7 @@
{% trans 'Username' %}: [{{ username }}]
{% trans 'Assets' %}: [{{ asset }}]
+{% trans 'Account' %}: [{{ account }}]
{% trans 'The user has just successfully logged into the asset. Please ensure that this is an authorized operation. If you suspect that this is an unauthorized access, please take appropriate measures immediately.' %}
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index b0756d4aa..6eb371827 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -419,9 +419,10 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView reviewers = acl.reviewers.all() if not reviewers: return + account_username = account.username self._record_operate_log(acl, asset) for reviewer in reviewers: - AssetLoginReminderMsg(reviewer, asset, user).publish_async() + AssetLoginReminderMsg(reviewer, asset, user, account_username).publish_async() class SuperConnectionTokenViewSet(ConnectionTokenViewSet): From 7eb497f9d30617f029c04c8cc5f75798e08a3e66 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Thu, 12 Oct 2023 20:13:21 +0800 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=E8=B5=84=E4=BA=A7=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E8=A2=AB=E9=99=90=E5=88=B6=EF=BC=8C=E6=B2=A1=E6=9C=89=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E5=88=B0=E5=BD=93=E5=89=8D=E7=BB=84=E7=BB=87=E7=9A=84?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=EF=BC=8C=E8=80=8C=E6=98=AF?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=88=B0=E5=85=A8=E5=B1=80=E7=BB=84=E7=BB=87?= =?UTF-8?q?=20(#11827)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- apps/authentication/api/connection_token.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 6eb371827..f51351b67 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -22,6 +22,7 @@ from common.utils import random_string, get_logger, get_request_ip from common.utils.django import get_request_os from common.utils.http import is_true, is_false from orgs.mixins.api import RootOrgViewMixin +from orgs.utils import tmp_to_org from perms.models import ActionChoices from terminal.connect_methods import NativeClient, ConnectMethodUtil from terminal.models import EndpointRule, Endpoint @@ -383,13 +384,14 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView @staticmethod def _record_operate_log(acl, asset): from audits.handler import create_or_update_operate_log - after = {str(_('Assets')): str(asset)} - object_name = acl._meta.object_name - resource_type = acl._meta.verbose_name - create_or_update_operate_log( - acl.action, resource_type, resource=acl, - after=after, object_name=object_name - ) + with tmp_to_org(asset.org_id): + after = {str(_('Assets')): str(asset)} + object_name = acl._meta.object_name + resource_type = acl._meta.verbose_name + create_or_update_operate_log( + acl.action, resource_type, resource=acl, + after=after, object_name=object_name + ) def _validate_acl(self, user, asset, account): from acls.models import LoginAssetACL From 588723a76cccae7efd8b53ec68e6c7cae081ff71 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:08:56 +0800 Subject: [PATCH 5/5] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=B5=84?= =?UTF-8?q?=E4=BA=A7=E7=99=BB=E5=BD=95=E9=80=9A=E7=9F=A5=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=20(#11834)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng <1304903146@qq.com> --- .../templates/acls/asset_login_reminder.html | 2 +- apps/authentication/api/connection_token.py | 28 +++--- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 98 ++++++++++--------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 97 +++++++++--------- 6 files changed, 128 insertions(+), 105 deletions(-) diff --git a/apps/acls/templates/acls/asset_login_reminder.html b/apps/acls/templates/acls/asset_login_reminder.html index 8d63a2ff6..af836cab5 100644 --- a/apps/acls/templates/acls/asset_login_reminder.html +++ b/apps/acls/templates/acls/asset_login_reminder.html @@ -7,7 +7,7 @@{% trans 'Account' %}: [{{ account }}]
{% trans 'The user has just successfully logged into the asset. Please ensure that this is an authorized operation. If you suspect that this is an unauthorized access, please take appropriate measures immediately.' %}
+{% trans 'The user has just logged in to the asset. Please ensure that this is an authorized operation. If you suspect that this is an unauthorized access, please take appropriate measures immediately.' %}
{% trans 'Thank you' %}!
diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index f51351b67..c14df034d 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -361,9 +361,10 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView if account.has_secret: data['input_secret'] = '' + input_username = data.get('input_username', '') if account.username != AliasAccount.INPUT: data['input_username'] = '' - ticket = self._validate_acl(user, asset, account) + ticket = self._validate_acl(user, asset, account, input_username) if ticket: data['from_ticket'] = ticket data['is_active'] = False @@ -382,10 +383,13 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView return account @staticmethod - def _record_operate_log(acl, asset): + def _record_operate_log(acl, asset, input_username): from audits.handler import create_or_update_operate_log with tmp_to_org(asset.org_id): - after = {str(_('Assets')): str(asset)} + after = { + str(_('Assets')): str(asset), + str(_('Account')): input_username + } object_name = acl._meta.object_name resource_type = acl._meta.verbose_name create_or_update_operate_log( @@ -393,7 +397,7 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView after=after, object_name=object_name ) - def _validate_acl(self, user, asset, account): + def _validate_acl(self, user, asset, account, input_username): from acls.models import LoginAssetACL acls = LoginAssetACL.filter_queryset(user=user, asset=asset, account=account) ip = get_request_ip(self.request) @@ -401,19 +405,19 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView if not acl: return if acl.is_action(acl.ActionChoices.accept): - self._record_operate_log(acl, asset) + self._record_operate_log(acl, asset, input_username) return if acl.is_action(acl.ActionChoices.reject): - self._record_operate_log(acl, asset) + self._record_operate_log(acl, asset, input_username) msg = _('ACL action is reject: {}({})'.format(acl.name, acl.id)) raise JMSException(code='acl_reject', detail=msg) if acl.is_action(acl.ActionChoices.review): if not self.request.query_params.get('create_ticket'): msg = _('ACL action is review') raise JMSException(code='acl_review', detail=msg) - self._record_operate_log(acl, asset) + self._record_operate_log(acl, asset, input_username) ticket = LoginAssetACL.create_login_asset_review_ticket( - user=user, asset=asset, account_username=account.username, + user=user, asset=asset, account_username=input_username, assignees=acl.reviewers.all(), org_id=asset.org_id ) return ticket @@ -421,10 +425,12 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView reviewers = acl.reviewers.all() if not reviewers: return - account_username = account.username - self._record_operate_log(acl, asset) + + self._record_operate_log(acl, asset, input_username) for reviewer in reviewers: - AssetLoginReminderMsg(reviewer, asset, user, account_username).publish_async() + AssetLoginReminderMsg( + reviewer, asset, user, input_username + ).publish_async() class SuperConnectionTokenViewSet(ConnectionTokenViewSet): diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index c1648acb8..50a9d1152 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:38bd8a6653f3f4dc63552b1c86379f82067f9f9daac227bacb3af3f9f62134f9 -size 161704 +oid sha256:d7366743ab156daec72625cd241f76420c551c6a48330266a57e3d0b808d4164 +size 162675 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 4ba81a5a4..f3fa1ddb4 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-12 09:51+0800\n" +"POT-Creation-Date: 2023-10-13 15:03+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME