From fa54a98d6c5990c99da25287355c3a0ee654b82f Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Thu, 8 Sep 2022 18:08:46 +0800 Subject: [PATCH 1/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8D=8E=E4=B8=BA?= =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E9=85=8D=E7=BD=AE=E9=94=99=E8=AF=AF=EF=BC=8C?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=8F=90=E7=A4=BA=E4=B8=8D=E5=AF=B9=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/sdk/sms/huawei.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/common/sdk/sms/huawei.py b/apps/common/sdk/sms/huawei.py index 154b554fd..c5d6bb116 100644 --- a/apps/common/sdk/sms/huawei.py +++ b/apps/common/sdk/sms/huawei.py @@ -86,7 +86,7 @@ class HuaweiSMS(BaseSMSClient): except Exception as error: raise JMSException(code='response_bad', detail=error) - if resp_msg.get('code' != '000000'): + if resp_msg.get('code') != '000000': raise JMSException(code='response_bad', detail=resp_msg) return resp_msg From 1ac64db0ba3a60284037b4646f0b755b8d82c2b7 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 9 Sep 2022 16:01:08 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=B4=A6=E5=8F=B7?= =?UTF-8?q?=E5=A4=87=E4=BB=BD=E5=A4=B1=E8=B4=A5=E9=97=AE=E9=A2=98=20(#8852?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/assets/task_handlers/backup/handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/task_handlers/backup/handlers.py b/apps/assets/task_handlers/backup/handlers.py index a29058fac..43e6a80db 100644 --- a/apps/assets/task_handlers/backup/handlers.py +++ b/apps/assets/task_handlers/backup/handlers.py @@ -158,7 +158,7 @@ class AppAccountHandler(BaseAccountHandler): continue for account in accounts: cls.replace_account_info(account, app_dict, system_user_dict) - data = AppAccountBackUpSerializer(accounts, many=True, app_type=app_type).data + data = AppAccountBackUpSerializer(accounts, many=True, tp=app_type).data data_map.update(cls.add_rows(data, header_fields, sheet_name)) logger.info('\n\033[33m- 共收集{}条应用账号\033[0m'.format(qs.count())) return data_map From 6bbbe312a2b529fc06ceea4f82cdb09360cb5db8 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 13 Sep 2022 11:26:26 +0800 Subject: [PATCH 3/6] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=8A=A0?= =?UTF-8?q?=E5=AF=86=EF=BC=8C=E6=B2=A1=E6=9C=89rsa=E5=88=99=E4=B8=8D?= =?UTF-8?q?=E5=8A=A0=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/static/js/jumpserver.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/static/js/jumpserver.js b/apps/static/js/jumpserver.js index c95c06c2c..b6bb6c6a4 100644 --- a/apps/static/js/jumpserver.js +++ b/apps/static/js/jumpserver.js @@ -1549,10 +1549,13 @@ function encryptPassword(password) { if (!password) { return '' } - const aesKey = (Math.random() + 1).toString(36).substring(2) // public key 是 base64 存储的 - const rsaPublicKeyText = getCookie('jms_public_key') - .replaceAll('"', '') + let rsaPublicKeyText = getCookie('jms_public_key') + if (!rsaPublicKeyText) { + return password + } + const aesKey = (Math.random() + 1).toString(36).substring(2) + rsaPublicKeyText = rsaPublicKeyText.replaceAll('"', '') const rsaPublicKey = atob(rsaPublicKeyText) const keyCipher = rsaEncrypt(aesKey, rsaPublicKey) const passwordCipher = aesEncrypt(password, aesKey) From 556bd3682e66bd690accd0125456ae92e70ff053 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Fri, 9 Sep 2022 19:05:36 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=AF=B9?= =?UTF-8?q?=E5=BC=80=E5=90=AFSSL/TLS=E7=9A=84MongoDb=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=94=B9=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/utils/file.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/apps/common/utils/file.py b/apps/common/utils/file.py index 9529fbdca..efc652870 100644 --- a/apps/common/utils/file.py +++ b/apps/common/utils/file.py @@ -4,6 +4,10 @@ import csv import pyzipper import requests +from hashlib import md5 + +from django.conf import settings + def create_csv_file(filename, headers, rows, ): with open(filename, 'w', encoding='utf-8-sig')as f: @@ -28,3 +32,18 @@ def download_file(src, path): with open(path, 'wb') as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) + + +def save_content_to_temp_path(content, file_mode=0o400): + if not content: + return + + project_dir = settings.PROJECT_DIR + tmp_dir = os.path.join(project_dir, 'tmp') + filename = '.' + md5(content.encode('utf-8')).hexdigest() + filepath = os.path.join(tmp_dir, filename) + if not os.path.exists(filepath): + with open(filepath, 'w') as f: + f.write(content) + os.chmod(filepath, file_mode) + return filepath From 93e1adf376c3253bab3a5fa02396468882a6f9f7 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Fri, 9 Sep 2022 15:38:59 +0800 Subject: [PATCH 5/6] =?UTF-8?q?perf:=20=E5=B7=A5=E5=8D=95=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E7=9B=B8=E5=85=B3=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/tickets/filters.py | 73 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/apps/tickets/filters.py b/apps/tickets/filters.py index bf20014cc..659556c12 100644 --- a/apps/tickets/filters.py +++ b/apps/tickets/filters.py @@ -1,5 +1,6 @@ from django_filters import rest_framework as filters -from django.db.models import Subquery, OuterRef +from django.db.models.functions import Concat +from django.db.models import Subquery, OuterRef, Value, F, Q from common.drf.filters import BaseFilterSet @@ -11,6 +12,10 @@ from tickets.models import ( class TicketFilter(BaseFilterSet): assignees__id = filters.UUIDFilter(method='filter_assignees_id') + relevant_app = filters.CharFilter(method='filter_relevant_app') + relevant_asset = filters.CharFilter(method='filter_relevant_asset') + relevant_system_user = filters.CharFilter(method='filter_relevant_system_user') + relevant_command = filters.CharFilter(method='filter_relevant_command') class Meta: model = Ticket @@ -27,6 +32,72 @@ class TicketFilter(BaseFilterSet): ticket_steps__ticket_assignees__assignee__id=value ) + def filter_relevant_asset(self, queryset, name, value): + asset_ids = ApplyAssetTicket.objects.annotate( + asset_str=Concat( + F('apply_assets__hostname'), Value('('), + F('apply_assets__ip'), Value(')') + ) + ).filter( + asset_str__icontains=value + ).values_list('id', flat=True) + + login_asset_ids = ApplyLoginAssetTicket.objects.annotate( + asset_str=Concat( + F('apply_login_asset__hostname'), Value('('), + F('apply_login_asset__ip'), Value(')') + ) + ).filter( + asset_str__icontains=value + ).values_list('id', flat=True) + + command_ids = ApplyCommandTicket.objects.filter( + apply_run_asset__icontains=value + ).values_list('id', flat=True) + + ticket_ids = list(set(list(asset_ids) + list(login_asset_ids) + list(command_ids))) + return queryset.filter(id__in=ticket_ids) + + def filter_relevant_app(self, queryset, name, value): + app_ids = ApplyApplicationTicket.objects.filter( + apply_applications__name__icontains=value + ).values_list('id', flat=True) + + command_ids = ApplyCommandTicket.objects.filter( + apply_run_asset__icontains=value + ).values_list('id', flat=True) + + ticket_ids = list(set(list(app_ids) + list(command_ids))) + return queryset.filter(id__in=ticket_ids) + + def filter_relevant_system_user(self, queryset, name, value): + system_user_query = Q(apply_system_users__name__icontains=value) + asset_ids = ApplyAssetTicket.objects.filter( + system_user_query + ).values_list('id', flat=True) + + app_ids = ApplyApplicationTicket.objects.filter( + system_user_query + ).values_list('id', flat=True) + + login_asset_ids = ApplyLoginAssetTicket.objects.filter( + apply_login_system_user__name__icontains=value + ).values_list('id', flat=True) + + command_ids = ApplyCommandTicket.objects.filter( + apply_run_system_user__name__icontains=value + ).values_list('id', flat=True) + ticket_ids = list( + set(list(asset_ids) + list(app_ids) + list(login_asset_ids) + list(command_ids)) + ) + return queryset.filter(id__in=ticket_ids) + + def filter_relevant_command(self, queryset, name, value): + command_ids = ApplyCommandTicket.objects.filter( + apply_run_command__icontains=value + ).values_list('id', flat=True) + return queryset.filter(id__in=list(command_ids)) + class ApplyAssetTicketFilter(BaseFilterSet): class Meta: From 5e16b6387ad59bef7a542691a44e6e79a98e1eaf Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 13 Sep 2022 17:20:09 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=85=8D=E7=BD=AE?= =?UTF-8?q?mfa=E5=A4=B1=E6=95=88=E6=97=A5=E6=9C=9F=20=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20(#8856)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/common/permissions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/common/permissions.py b/apps/common/permissions.py index 869107a58..b6ba60ac9 100644 --- a/apps/common/permissions.py +++ b/apps/common/permissions.py @@ -70,7 +70,8 @@ class UserConfirmation(permissions.BasePermission): return True @classmethod - def require(cls, confirm_type=ConfirmType.ReLogin, ttl=300): + def require(cls, confirm_type=ConfirmType.ReLogin, ttl=60 * 5): min_level = ConfirmType.values.index(confirm_type) + 1 + ttl = settings.SECURITY_MFA_VERIFY_TTL if confirm_type == ConfirmType.MFA else ttl name = 'UserConfirmationLevel{}TTL{}'.format(min_level, ttl) return type(name, (cls,), {'min_level': min_level, 'ttl': ttl, 'confirm_type': confirm_type})