From 0f338a3b58b2ea79b876c380a90dbfe4a5353626 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 24 Feb 2023 00:04:53 +0800 Subject: [PATCH 01/91] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=E7=A4=BE?= =?UTF-8?q?=E5=8C=BA=E7=89=88=E5=8F=AF=E8=83=BD=E5=BC=95=E8=B5=B7=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/assets/models/node.py | 2 +- apps/perms/utils/account.py | 10 ++++++---- apps/rbac/permissions.py | 6 +++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/assets/models/node.py b/apps/assets/models/node.py index 8f6ee45f3..32bfcaa09 100644 --- a/apps/assets/models/node.py +++ b/apps/assets/models/node.py @@ -489,7 +489,7 @@ class SomeNodesMixin: return cls.default_node() if ori_org and ori_org.is_root(): - return None + return cls.default_node() org_roots = cls.org_root_nodes() org_roots_length = len(org_roots) diff --git a/apps/perms/utils/account.py b/apps/perms/utils/account.py index 16e8bb344..b66b247d8 100644 --- a/apps/perms/utils/account.py +++ b/apps/perms/utils/account.py @@ -1,5 +1,6 @@ from collections import defaultdict +from orgs.utils import tmp_to_org from accounts.models import Account from accounts.const import AliasAccount from .permission import AssetPermissionUtil @@ -16,10 +17,11 @@ class PermAccountUtil(AssetPermissionUtil): :param asset: Asset :param account_name: 可能是 @USER @INPUT 字符串 """ - permed_accounts = self.get_permed_accounts_for_user(user, asset) - accounts_mapper = {account.alias: account for account in permed_accounts} - account = accounts_mapper.get(account_name) - return account + with tmp_to_org(asset.org): + permed_accounts = self.get_permed_accounts_for_user(user, asset) + accounts_mapper = {account.alias: account for account in permed_accounts} + account = accounts_mapper.get(account_name) + return account def get_permed_accounts_for_user(self, user, asset): """ 获取授权给用户某个资产的账号 """ diff --git a/apps/rbac/permissions.py b/apps/rbac/permissions.py index 7cc35d370..7c3f21610 100644 --- a/apps/rbac/permissions.py +++ b/apps/rbac/permissions.py @@ -97,13 +97,13 @@ class RBACPermission(permissions.DjangoModelPermissions): else: model_cls = queryset.model except AssertionError as e: - logger.error(f'Error get model cls: {e}') + # logger.error(f'Error get model cls: {e}') model_cls = None except AttributeError as e: - logger.error(f'Error get model cls: {e}') + # logger.error(f'Error get model cls: {e}') model_cls = None except Exception as e: - logger.error('Error get model class: {} of {}'.format(e, view)) + # logger.error('Error get model class: {} of {}'.format(e, view)) raise e return model_cls From 4650652faf0a60e707c2775fa9a08cee855da7d0 Mon Sep 17 00:00:00 2001 From: maninhill <41712985+maninhill@users.noreply.github.com> Date: Thu, 23 Feb 2023 23:02:51 +0800 Subject: [PATCH 02/91] =?UTF-8?q?perf=EF=BC=9A=E6=9B=B4=E6=96=B0=20README?= =?UTF-8?q?=20=E4=B8=AD=E7=9A=84=E4=BA=A7=E5=93=81=20UI=20=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E6=88=AA=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cc7d85f8d..70fe9db80 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运 ## UI 展示 -![UI展示](https://www.jumpserver.org/images/screenshot/1.png) +![UI展示](https://docs.jumpserver.org/zh/v3/img/dashboard.png) ## 在线体验 @@ -41,8 +41,7 @@ JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运 ## 快速开始 -- [极速安装](https://docs.jumpserver.org/zh/master/install/setup_by_fast/) -- [手动安装](https://github.com/jumpserver/installer) +- [快速入门](https://docs.jumpserver.org/zh/v3/quick_start/) - [产品文档](https://docs.jumpserver.org) - [知识库](https://kb.fit2cloud.com/categories/jumpserver) From 1b2de703f482f62db0adde7545e0ef99e817e4ca Mon Sep 17 00:00:00 2001 From: Bai Date: Fri, 24 Feb 2023 11:27:38 +0800 Subject: [PATCH 03/91] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=8E=88=E6=9D=83=E8=B5=84=E4=BA=A7=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E6=97=B6=E8=BF=94=E5=9B=9E=20spec=5Finfo=20=E5=AD=97=E6=AE=B5,?= =?UTF-8?q?=20=E8=A7=A3=E5=86=B3=E8=BF=9E=E6=8E=A5=20Magnus=20=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/perms/api/user_permission/assets.py | 6 ++++++ apps/perms/serializers/user_permission.py | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/perms/api/user_permission/assets.py b/apps/perms/api/user_permission/assets.py index 0daa23791..f94854164 100644 --- a/apps/perms/api/user_permission/assets.py +++ b/apps/perms/api/user_permission/assets.py @@ -30,6 +30,12 @@ class BaseUserPermedAssetsApi(SelfOrPKUserMixin, ListAPIView): filterset_class = AssetFilterSet serializer_class = serializers.AssetPermedSerializer + def get_serializer_class(self): + serializer_class = super().get_serializer_class() + if self.request.query_params.get('id'): + serializer_class = serializers.AssetPermedDetailSerializer + return serializer_class + def get_queryset(self): if getattr(self, 'swagger_fake_view', False): return Asset.objects.none() diff --git a/apps/perms/serializers/user_permission.py b/apps/perms/serializers/user_permission.py index 34143d936..c9582cc11 100644 --- a/apps/perms/serializers/user_permission.py +++ b/apps/perms/serializers/user_permission.py @@ -15,7 +15,7 @@ from perms.serializers.permission import ActionChoicesField __all__ = [ 'NodePermedSerializer', 'AssetPermedSerializer', - 'AccountsPermedSerializer' + 'AssetPermedDetailSerializer', 'AccountsPermedSerializer' ] @@ -46,6 +46,12 @@ class AssetPermedSerializer(OrgResourceModelSerializerMixin): return queryset +class AssetPermedDetailSerializer(AssetPermedSerializer): + class Meta(AssetPermedSerializer.Meta): + fields = AssetPermedSerializer.Meta.fields + ['spec_info'] + read_only_fields = fields + + class NodePermedSerializer(serializers.ModelSerializer): class Meta: model = Node From a4a871ff2b48972591f119b075b6164a6349f230 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 24 Feb 2023 12:16:45 +0800 Subject: [PATCH 04/91] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E4=BB=8A=E6=97=A5=E6=B4=BB=E8=B7=83=E8=B5=84=E4=BA=A7?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E9=80=BB=E8=BE=91=20(#9745)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bai --- apps/orgs/caches.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/orgs/caches.py b/apps/orgs/caches.py index 1eb54e037..b1f8fbdea 100644 --- a/apps/orgs/caches.py +++ b/apps/orgs/caches.py @@ -114,9 +114,7 @@ class OrgResourceStatisticsCache(OrgRelatedCache): @staticmethod def compute_total_count_today_active_assets(): t = local_zero_hour() - return Session.objects.filter( - date_start__gte=t, is_success=False - ).values('asset_id').distinct().count() + return Session.objects.filter(date_start__gte=t).values('asset_id').distinct().count() @staticmethod def compute_total_count_today_failed_sessions(): From 63ca4f8fab590a0cc010697eb654e1e75bdb90f7 Mon Sep 17 00:00:00 2001 From: Bai Date: Fri, 24 Feb 2023 14:23:19 +0800 Subject: [PATCH 05/91] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AE=A4?= =?UTF-8?q?=E8=AF=81MFA=E5=A4=B1=E8=B4=A5=E6=AC=A1=E6=95=B0=E6=B8=85?= =?UTF-8?q?=E7=A9=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/mixins.py | 1 + apps/authentication/views/mfa.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/apps/authentication/mixins.py b/apps/authentication/mixins.py index 5355d79bd..14e5fd35f 100644 --- a/apps/authentication/mixins.py +++ b/apps/authentication/mixins.py @@ -225,6 +225,7 @@ class MFAMixin: self.request.session['auth_mfa_time'] = time.time() self.request.session['auth_mfa_required'] = 0 self.request.session['auth_mfa_type'] = mfa_type + MFABlockUtils(self.request.user.username, self.get_request_ip()).clean_failed_count() def clean_mfa_mark(self): keys = ['auth_mfa', 'auth_mfa_time', 'auth_mfa_required', 'auth_mfa_type'] diff --git a/apps/authentication/views/mfa.py b/apps/authentication/views/mfa.py index fd8b80e32..c297a3261 100644 --- a/apps/authentication/views/mfa.py +++ b/apps/authentication/views/mfa.py @@ -32,11 +32,14 @@ class UserLoginMFAView(mixins.AuthMixin, FormView): return super().get(*args, **kwargs) def form_valid(self, form): + from users.utils import MFABlockUtils code = form.cleaned_data.get('code') mfa_type = form.cleaned_data.get('mfa_type') try: self._do_check_user_mfa(code, mfa_type) + user, ip = self.get_user_from_session(), self.get_request_ip() + MFABlockUtils(user.username, ip).clean_failed_count() return redirect_to_guard_view('mfa_ok') except (errors.MFAFailedError, errors.BlockMFAError) as e: form.add_error('code', e.msg) From 22a1d60e3fc1edc1062cd08a360ad293d84ff151 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 24 Feb 2023 14:33:37 +0800 Subject: [PATCH 06/91] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20msg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/serializers/label.py | 3 ++- apps/common/serializers/mixin.py | 10 ++++++---- apps/common/signal_handlers.py | 5 ++++- apps/jumpserver/context_processor.py | 2 +- apps/templates/_base_only_content.html | 6 +++++- apps/templates/flash_message_standalone.html | 4 ++-- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/apps/assets/serializers/label.py b/apps/assets/serializers/label.py index 6992f4e8d..48bc0885f 100644 --- a/apps/assets/serializers/label.py +++ b/apps/assets/serializers/label.py @@ -29,7 +29,8 @@ class LabelSerializer(BulkOrgResourceModelSerializer): @classmethod def setup_eager_loading(cls, queryset): - queryset = queryset.annotate(asset_count=Count('assets')) + queryset = queryset.prefetch_related('assets') \ + .annotate(asset_count=Count('assets')) return queryset diff --git a/apps/common/serializers/mixin.py b/apps/common/serializers/mixin.py index 7f4678557..4d3e6ddc8 100644 --- a/apps/common/serializers/mixin.py +++ b/apps/common/serializers/mixin.py @@ -55,9 +55,11 @@ class BulkSerializerMixin(object): # add update_lookup_field field back to validated data # since super by default strips out read-only fields # hence id will no longer be present in validated_data - if all((isinstance(self.root, BulkListSerializer), - id_attr, - request_method in ('PUT', 'PATCH'))): + if all([ + isinstance(self.root, BulkListSerializer), + id_attr, + request_method in ('PUT', 'PATCH') + ]): id_field = self.fields.get("id") or self.fields.get('pk') if data.get("id"): id_value = id_field.to_internal_value(data.get("id")) @@ -135,7 +137,7 @@ class BulkListSerializerMixin: pk = item["pk"] else: raise ValidationError("id or pk not in data") - child = self.instance.get(id=pk) + child = self.instance.get(pk=pk) self.child.instance = child self.child.initial_data = item # raw diff --git a/apps/common/signal_handlers.py b/apps/common/signal_handlers.py index d03c76798..6beb2d187 100644 --- a/apps/common/signal_handlers.py +++ b/apps/common/signal_handlers.py @@ -32,7 +32,7 @@ class Counter: return self.counter == other.counter -def on_request_finished_logging_db_query(sender, **kwargs): +def digest_sql_query(): queries = connection.queries counters = defaultdict(Counter) table_queries = defaultdict(list) @@ -79,6 +79,9 @@ def on_request_finished_logging_db_query(sender, **kwargs): counter.counter, counter.time, name) ) + +def on_request_finished_logging_db_query(sender, **kwargs): + digest_sql_query() on_request_finished_release_local(sender, **kwargs) diff --git a/apps/jumpserver/context_processor.py b/apps/jumpserver/context_processor.py index 4d5f9a4cf..9966228dc 100644 --- a/apps/jumpserver/context_processor.py +++ b/apps/jumpserver/context_processor.py @@ -20,7 +20,7 @@ default_context = { 'LOGIN_WECOM_logo_logout': static('img/login_wecom_logo.png'), 'LOGIN_DINGTALK_logo_logout': static('img/login_dingtalk_logo.png'), 'LOGIN_FEISHU_logo_logout': static('img/login_feishu_logo.png'), - 'COPYRIGHT': 'FIT2CLOUD 飞致云' + ' © 2014-2022', + 'COPYRIGHT': 'FIT2CLOUD 飞致云' + ' © 2014-2023', 'INTERFACE': default_interface, } diff --git a/apps/templates/_base_only_content.html b/apps/templates/_base_only_content.html index 87a4c9870..af02b18e7 100644 --- a/apps/templates/_base_only_content.html +++ b/apps/templates/_base_only_content.html @@ -18,6 +18,10 @@ margin: 0 auto; padding: 100px 20px 20px 20px; } + + .ibox-content { + padding: 30px; + } {% block custom_head_css_js %} {% endblock %} @@ -30,7 +34,7 @@

{% block title %}{% endblock %}

-
+
{% block content %} {% endblock %}
diff --git a/apps/templates/flash_message_standalone.html b/apps/templates/flash_message_standalone.html index 61b431b9a..ad81c1141 100644 --- a/apps/templates/flash_message_standalone.html +++ b/apps/templates/flash_message_standalone.html @@ -23,7 +23,7 @@
{% if has_cancel %} -
+
{% trans 'Cancel' %} @@ -43,7 +43,7 @@ {% endblock %} {% block custom_foot_js %} -