From 18a390d66aba2e21dbf5e1efc9ee67fc6c55f0c1 Mon Sep 17 00:00:00 2001 From: Bai Date: Wed, 17 Mar 2021 11:08:20 +0800 Subject: [PATCH 01/13] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E6=96=87=E4=BB=B6(default=5Forg=5Fname:=20DEFAULT=20?= =?UTF-8?q?=3D>=20Default)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/orgs/migrations/0010_auto_20210219_1241.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/orgs/migrations/0010_auto_20210219_1241.py b/apps/orgs/migrations/0010_auto_20210219_1241.py index 37b40e350..f5694d7bc 100644 --- a/apps/orgs/migrations/0010_auto_20210219_1241.py +++ b/apps/orgs/migrations/0010_auto_20210219_1241.py @@ -11,7 +11,7 @@ default_id = '00000000-0000-0000-0000-000000000002' def add_default_org(apps, schema_editor): org_cls = apps.get_model('orgs', 'Organization') - defaults = {'name': 'DEFAULT', 'id': default_id} + defaults = {'name': 'Default', 'id': default_id} org_cls.objects.get_or_create(defaults=defaults, id=default_id) From d3bbfdc45805741f668e807f30d579207edd33d1 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 17 Mar 2021 10:19:35 +0800 Subject: [PATCH 02/13] =?UTF-8?q?perf:=20=E4=B8=8D=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=8E=9F=E6=9D=A5=E7=9A=84=E9=BB=98=E8=AE=A4=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index a9bbce183..f4a1c6641 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -283,7 +283,7 @@ class Config(dict): 'SERVER_REPLAY_STORAGE': {}, 'CONNECTION_TOKEN_ENABLED': False, 'ONLY_ALLOW_EXIST_USER_AUTH': False, - 'ONLY_ALLOW_AUTH_FROM_SOURCE': True, + 'ONLY_ALLOW_AUTH_FROM_SOURCE': False, 'DISK_CHECK_ENABLED': True, 'SESSION_SAVE_EVERY_REQUEST': True, 'SESSION_EXPIRE_AT_BROWSER_CLOSE_FORCE': False, From 817268d7cd0e0fcd64dae2274db78586d37a0fc8 Mon Sep 17 00:00:00 2001 From: xinwen Date: Wed, 17 Mar 2021 10:24:12 +0800 Subject: [PATCH 03/13] =?UTF-8?q?perf:=20=E8=B5=84=E4=BA=A7=E4=B8=8E?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=8F=98=E5=8C=96=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E5=8F=91=E9=80=81=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7=E4=BF=A1=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/models/user.py | 9 ++++++++- apps/assets/signals_handler/common.py | 3 ++- apps/assets/tasks/utils.py | 15 +++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index e8cf770f5..1640c7f32 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -87,6 +87,9 @@ class SystemUser(BaseUser): (PROTOCOL_POSTGRESQL, 'postgresql'), (PROTOCOL_K8S, 'k8s'), ) + + SUPPORT_PUSH_PROTOCOLS = [PROTOCOL_SSH, PROTOCOL_RDP] + ASSET_CATEGORY_PROTOCOLS = [ PROTOCOL_SSH, PROTOCOL_RDP, PROTOCOL_TELNET, PROTOCOL_VNC ] @@ -151,11 +154,15 @@ class SystemUser(BaseUser): return self.get_login_mode_display() def is_need_push(self): - if self.auto_push and self.protocol in [self.PROTOCOL_SSH, self.PROTOCOL_RDP]: + if self.auto_push and self.is_protocol_support_push: return True else: return False + @property + def is_protocol_support_push(self): + return self.protocol in self.SUPPORT_PUSH_PROTOCOLS + @property def is_need_cmd_filter(self): return self.protocol not in [self.PROTOCOL_RDP, self.PROTOCOL_VNC] diff --git a/apps/assets/signals_handler/common.py b/apps/assets/signals_handler/common.py index af6a7895c..50f7f41f1 100644 --- a/apps/assets/signals_handler/common.py +++ b/apps/assets/signals_handler/common.py @@ -193,7 +193,8 @@ def on_asset_nodes_add(instance, action, reverse, pk_set, **kwargs): systemuser_id=system_user_id, asset_id=asset_id )) - push_system_user_to_assets.delay(system_user_id, asset_ids_to_push) + if asset_ids_to_push: + push_system_user_to_assets.delay(system_user_id, asset_ids_to_push) m2m_model.objects.bulk_create(to_create) diff --git a/apps/assets/tasks/utils.py b/apps/assets/tasks/utils.py index 9956665ee..93aaa4bfc 100644 --- a/apps/assets/tasks/utils.py +++ b/apps/assets/tasks/utils.py @@ -25,10 +25,13 @@ def check_asset_can_run_ansible(asset): def check_system_user_can_run_ansible(system_user): - if not system_user.is_need_push(): - msg = _("Push system user task skip, auto push not enable or " - "protocol is not ssh or rdp: {}").format(system_user.name) - logger.info(msg) + if not system_user.auto_push: + logger.warn(f'Push system user task skip, auto push not enable: system_user={system_user.name}') + return False + if not system_user.is_protocol_support_push: + logger.warn(f'Push system user task skip, protocol not support: ' + f'system_user={system_user.name} protocol={system_user.protocol} ' + f'support_protocol={system_user.SUPPORT_PUSH_PROTOCOLS}') return False # Push root as system user is dangerous @@ -37,10 +40,6 @@ def check_system_user_can_run_ansible(system_user): logger.info(msg) return False - # if system_user.protocol != "ssh": - # msg = _("System user protocol not ssh: {}".format(system_user)) - # logger.info(msg) - # return False return True From 9b85aafa52fd3e4545c2c6805f3c5bcb8f8ae36c Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 17 Mar 2021 13:01:59 +0800 Subject: [PATCH 04/13] =?UTF-8?q?perf:=20=E5=85=A8=E5=B1=80=E7=BB=84?= =?UTF-8?q?=E7=BB=87=E4=BB=85=E6=94=AF=E6=8C=81=E5=88=A0=E9=99=A4=E5=92=8C?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/zh/LC_MESSAGES/django.mo | Bin 73470 -> 73608 bytes apps/locale/zh/LC_MESSAGES/django.po | 237 ++++++++++++++------------- apps/orgs/mixins/api.py | 23 ++- 3 files changed, 145 insertions(+), 115 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 3a6dfef4d1b51da4c84fe5c8a1cb1d77af8d10cb..2d48fa05da7d6fc58eb85afdc6a41a318e6a0aef 100644 GIT binary patch delta 20810 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 z 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 delta 20648 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 O^Ei8k^&MZ9j{ZMZ)yg>l diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 20e7cc254..4bcdd69e4 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-03-11 17:54+0800\n" +"POT-Creation-Date: 2021-03-17 11:21+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -126,12 +126,12 @@ msgstr "动作" #: acls/serializers/login_acl.py:28 assets/models/label.py:15 #: audits/models.py:36 audits/models.py:56 audits/models.py:69 #: audits/serializers.py:81 authentication/models.py:44 -#: authentication/models.py:95 orgs/models.py:18 orgs/models.py:403 +#: authentication/models.py:95 orgs/models.py:18 orgs/models.py:420 #: perms/models/base.py:50 templates/index.html:78 #: terminal/backends/command/models.py:18 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:37 #: tickets/models/comment.py:17 users/models/user.py:159 -#: users/models/user.py:677 users/serializers/group.py:20 +#: users/models/user.py:684 users/serializers/group.py:20 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -156,9 +156,9 @@ msgstr "系统用户" #: acls/models/login_asset_acl.py:22 #: applications/serializers/attrs/application_category/remote_app.py:33 #: assets/models/asset.py:355 assets/models/authbook.py:26 -#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:29 +#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:30 #: assets/serializers/asset_user.py:47 assets/serializers/asset_user.py:84 -#: assets/serializers/system_user.py:191 audits/models.py:38 +#: assets/serializers/system_user.py:192 audits/models.py:38 #: perms/models/asset_permission.py:99 templates/index.html:82 #: terminal/backends/command/models.py:19 #: terminal/backends/command/serializers.py:13 terminal/models/session.py:39 @@ -192,7 +192,7 @@ msgstr "IP 地址无效: `{}`" msgid "IP" msgstr "IP" -#: acls/serializers/login_acl.py:41 +#: acls/serializers/login_acl.py:45 msgid "The user `{}` is not in the current organization: `{}`" msgstr "用户 `{}` 不在当前组织: `{}`" @@ -241,12 +241,12 @@ msgstr "协议选项: {}" msgid "Unsupported protocols: {}" msgstr "不支持的协议: {}" -#: acls/serializers/login_asset_acl.py:78 +#: acls/serializers/login_asset_acl.py:80 #: tickets/serializers/ticket/ticket.py:109 msgid "The organization `{}` does not exist" msgstr "组织 `{}` 不存在" -#: acls/serializers/login_asset_acl.py:83 +#: acls/serializers/login_asset_acl.py:85 msgid "None of the reviewers belong to Organization `{}`" msgstr "所有复核人都不属于组织 `{}`" @@ -335,7 +335,7 @@ msgstr "目标URL" #: applications/serializers/attrs/application_type/vmware_client.py:30 #: assets/models/base.py:252 assets/serializers/asset_user.py:71 #: audits/signals_handler.py:46 authentication/forms.py:22 -#: authentication/templates/authentication/login.html:148 +#: authentication/templates/authentication/login.html:155 #: settings/serializers/settings.py:89 users/forms/profile.py:21 #: users/templates/users/user_otp_check_password.html:13 #: users/templates/users/user_password_update.html:43 @@ -394,7 +394,8 @@ msgstr "基础" msgid "Charset" msgstr "编码" -#: assets/models/asset.py:145 tickets/models/ticket.py:40 +#: assets/models/asset.py:145 assets/serializers/asset.py:171 +#: tickets/models/ticket.py:40 msgid "Meta" msgstr "元数据" @@ -503,7 +504,7 @@ msgstr "标签管理" #: assets/models/cluster.py:28 assets/models/cmd_filter.py:26 #: assets/models/cmd_filter.py:60 assets/models/group.py:21 #: common/db/models.py:70 common/mixins/models.py:49 orgs/models.py:24 -#: orgs/models.py:407 perms/models/base.py:55 users/models/user.py:571 +#: orgs/models.py:424 perms/models/base.py:55 users/models/user.py:571 #: users/serializers/group.py:35 users/templates/users/user_detail.html:97 #: xpack/plugins/change_auth_plan/models.py:81 #: xpack/plugins/cloud/models.py:104 xpack/plugins/gathered_user/models.py:30 @@ -517,7 +518,7 @@ msgstr "创建者" #: assets/models/gathered_user.py:19 assets/models/group.py:22 #: assets/models/label.py:25 common/db/models.py:72 common/mixins/models.py:50 #: ops/models/adhoc.py:38 ops/models/command.py:29 orgs/models.py:25 -#: orgs/models.py:405 perms/models/base.py:56 users/models/group.py:18 +#: orgs/models.py:422 perms/models/base.py:56 users/models/group.py:18 #: users/templates/users/user_group_detail.html:58 #: xpack/plugins/cloud/models.py:107 msgid "Date created" @@ -553,7 +554,7 @@ msgstr "SSH公钥" #: assets/models/base.py:257 assets/models/gathered_user.py:20 #: common/db/models.py:73 common/mixins/models.py:51 ops/models/adhoc.py:39 -#: orgs/models.py:406 +#: orgs/models.py:423 msgid "Date updated" msgstr "更新日期" @@ -591,7 +592,7 @@ msgid "Default" msgstr "默认" #: assets/models/cluster.py:36 assets/models/label.py:14 -#: users/models/user.py:689 +#: users/models/user.py:696 msgid "System" msgstr "系统" @@ -664,7 +665,7 @@ msgstr "资产组" msgid "Default asset group" msgstr "默认资产组" -#: assets/models/label.py:19 assets/models/node.py:575 settings/models.py:30 +#: assets/models/label.py:19 assets/models/node.py:601 settings/models.py:30 msgid "Value" msgstr "值" @@ -672,23 +673,23 @@ msgstr "值" msgid "New node" msgstr "新节点" -#: assets/models/node.py:467 users/templates/users/_granted_assets.html:130 +#: assets/models/node.py:466 users/templates/users/_granted_assets.html:130 msgid "empty" msgstr "空" -#: assets/models/node.py:574 perms/models/asset_permission.py:156 +#: assets/models/node.py:600 perms/models/asset_permission.py:156 msgid "Key" msgstr "键" -#: assets/models/node.py:576 +#: assets/models/node.py:602 msgid "Full value" msgstr "全称" -#: assets/models/node.py:579 perms/models/asset_permission.py:157 +#: assets/models/node.py:605 perms/models/asset_permission.py:157 msgid "Parent key" msgstr "ssh私钥" -#: assets/models/node.py:588 assets/serializers/system_user.py:190 +#: assets/models/node.py:614 assets/serializers/system_user.py:191 #: users/templates/users/user_asset_permission.html:41 #: users/templates/users/user_asset_permission.html:73 #: users/templates/users/user_asset_permission.html:158 @@ -858,6 +859,17 @@ msgstr "应用数量" msgid "Gateways count" msgstr "网关数量" +#: assets/serializers/label.py:13 assets/serializers/system_user.py:45 +#: assets/serializers/system_user.py:166 +#: perms/serializers/asset/permission.py:66 +msgid "Assets amount" +msgstr "资产数量" + +#: assets/serializers/label.py:14 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:24 +msgid "Category display" +msgstr "类别 (显示名称)" + #: assets/serializers/node.py:18 msgid "value" msgstr "值" @@ -870,22 +882,17 @@ msgstr "不能包含: /" msgid "The same level node name cannot be the same" msgstr "同级别节点名字不能重复" -#: assets/serializers/system_user.py:44 assets/serializers/system_user.py:164 +#: assets/serializers/system_user.py:44 assets/serializers/system_user.py:165 #: perms/serializers/asset/permission.py:67 msgid "Nodes amount" msgstr "节点数量" -#: assets/serializers/system_user.py:45 assets/serializers/system_user.py:165 -#: perms/serializers/asset/permission.py:66 -msgid "Assets amount" -msgstr "资产数量" - -#: assets/serializers/system_user.py:46 assets/serializers/system_user.py:166 -#: assets/serializers/system_user.py:192 +#: assets/serializers/system_user.py:46 assets/serializers/system_user.py:167 +#: assets/serializers/system_user.py:193 msgid "Login mode display" msgstr "登录模式(显示名称)" -#: assets/serializers/system_user.py:48 assets/serializers/system_user.py:168 +#: assets/serializers/system_user.py:48 assets/serializers/system_user.py:169 msgid "Ad domain" msgstr "Ad 网域" @@ -1165,7 +1172,7 @@ msgstr "用户代理" #: authentication/templates/authentication/_mfa_confirm_modal.html:14 #: authentication/templates/authentication/login_otp.html:6 #: users/forms/profile.py:64 users/models/user.py:552 -#: users/serializers/profile.py:102 users/templates/users/user_detail.html:77 +#: users/serializers/profile.py:104 users/templates/users/user_detail.html:77 #: users/templates/users/user_profile.html:87 msgid "MFA" msgstr "多因子认证" @@ -1349,8 +1356,8 @@ msgid "" "after {} minutes)" msgstr "账号已被锁定(请联系管理员解锁 或 {}分钟后重试)" -#: authentication/errors.py:55 users/views/profile/otp.py:110 -#: users/views/profile/otp.py:149 users/views/profile/otp.py:169 +#: authentication/errors.py:55 users/views/profile/otp.py:107 +#: users/views/profile/otp.py:146 users/views/profile/otp.py:166 msgid "MFA code invalid, or ntp sync server time" msgstr "MFA验证码不正确,或者服务器端时间不对" @@ -1429,7 +1436,7 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: users/models/user.py:445 users/serializers/profile.py:99 +#: users/models/user.py:445 users/serializers/profile.py:101 #: users/templates/users/user_profile.html:94 #: users/templates/users/user_profile.html:163 #: users/templates/users/user_profile.html:166 @@ -1438,7 +1445,7 @@ msgid "Disable" msgstr "禁用" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:446 users/serializers/profile.py:100 +#: users/models/user.py:446 users/serializers/profile.py:102 #: users/templates/users/user_profile.html:92 #: users/templates/users/user_profile.html:170 msgid "Enable" @@ -1487,30 +1494,30 @@ msgstr "确认" msgid "Code error" msgstr "代码错误" -#: authentication/templates/authentication/login.html:141 +#: authentication/templates/authentication/login.html:148 msgid "Welcome back, please enter username and password to login" msgstr "欢迎回来,请输入用户名和密码登录" -#: authentication/templates/authentication/login.html:167 +#: authentication/templates/authentication/login.html:174 #: users/templates/users/forgot_password.html:15 #: users/templates/users/forgot_password.html:16 msgid "Forgot password" msgstr "忘记密码" -#: authentication/templates/authentication/login.html:174 +#: authentication/templates/authentication/login.html:181 #: templates/_header_bar.html:83 msgid "Login" msgstr "登录" -#: authentication/templates/authentication/login.html:181 +#: authentication/templates/authentication/login.html:188 msgid "More login options" msgstr "更多登录方式" -#: authentication/templates/authentication/login.html:184 +#: authentication/templates/authentication/login.html:191 msgid "OpenID" msgstr "OpenID" -#: authentication/templates/authentication/login.html:189 +#: authentication/templates/authentication/login.html:196 msgid "CAS" msgstr "" @@ -1833,15 +1840,15 @@ msgstr "{} 任务结束" msgid "Date finished" msgstr "结束日期" -#: ops/models/command.py:74 +#: ops/models/command.py:78 msgid "Task start" msgstr "任务开始" -#: ops/models/command.py:96 +#: ops/models/command.py:100 msgid "Command `{}` is forbidden ........" msgstr "命令 `{}` 不允许被执行 ......." -#: ops/models/command.py:109 +#: ops/models/command.py:113 msgid "Task end" msgstr "任务结束" @@ -1865,16 +1872,21 @@ msgstr "更新任务内容: {}" msgid "Disk used more than 80%: {} => {}" msgstr "磁盘使用率超过 80%: {} => {}" -#: orgs/api.py:64 -msgid "Organization contains undeleted resources" -msgstr "组织包含未删除的资源" +#: orgs/api.py:76 +#, python-brace-format +msgid "Have `{model._meta.verbose_name}` exists, Please delete" +msgstr "`{model._meta.verbose_name}` 存在数据, 请先删除" -#: orgs/api.py:68 +#: orgs/api.py:80 msgid "The current organization cannot be deleted" msgstr "当前组织不能被删除" +#: orgs/mixins/api.py:46 +msgid "Root organization only allow view and delete" +msgstr "全局组织仅支持 查看和删除" + #: orgs/mixins/models.py:45 orgs/mixins/serializers.py:25 orgs/models.py:36 -#: orgs/models.py:402 orgs/serializers.py:101 +#: orgs/models.py:419 orgs/serializers.py:101 #: tickets/serializers/ticket/ticket.py:81 msgid "Organization" msgstr "组织" @@ -1891,7 +1903,7 @@ msgstr "组织审计员" msgid "GLOBAL" msgstr "全局组织" -#: orgs/models.py:404 users/models/user.py:540 +#: orgs/models.py:421 users/models/user.py:540 #: users/templates/users/_select_user_modal.html:15 #: users/templates/users/user_detail.html:73 #: users/templates/users/user_list.html:16 @@ -1998,11 +2010,13 @@ msgid "" "permission type. ({})" msgstr "应用列表中包含与授权类型不同的应用。({})" -#: perms/serializers/asset/permission.py:61 users/serializers/user.py:67 +#: perms/serializers/asset/permission.py:43 +#: perms/serializers/asset/permission.py:61 users/serializers/user.py:34 +#: users/serializers/user.py:69 msgid "Is expired" msgstr "是否过期" -#: perms/serializers/asset/permission.py:62 users/serializers/user.py:66 +#: perms/serializers/asset/permission.py:62 users/serializers/user.py:68 msgid "Is valid" msgstr "账户是否有效" @@ -2022,7 +2036,7 @@ msgstr "系统用户数量" msgid "Test mail sent to {}, please check" msgstr "邮件已经发送{}, 请检查" -#: settings/api/common.py:110 xpack/plugins/interface/api.py:18 +#: settings/api/common.py:107 xpack/plugins/interface/api.py:18 #: xpack/plugins/interface/models.py:36 msgid "Welcome to the JumpServer open source Bastion Host" msgstr "欢迎使用JumpServer开源堡垒机" @@ -3423,10 +3437,6 @@ msgstr "受理人" msgid "Assignees display" msgstr "受理人 (显示名称)" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:24 -msgid "Category display" -msgstr "类别 (显示名称)" - #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:31 #: tickets/serializers/ticket/ticket.py:19 msgid "Type display" @@ -3558,7 +3568,7 @@ msgstr "工单已处理 - {} ({})" msgid "Your ticket has been processed, processor - {}" msgstr "你的工单已被处理, 处理人 - {}" -#: users/api/user.py:200 +#: users/api/user.py:212 msgid "Could not reset self otp, use profile reset instead" msgstr "不能在该页面重置多因子认证, 请去个人信息页面重置" @@ -3638,8 +3648,8 @@ msgstr "复制你的公钥到这里" msgid "Public key should not be the same as your old one." msgstr "不能和原来的密钥相同" -#: users/forms/profile.py:149 users/serializers/profile.py:74 -#: users/serializers/profile.py:147 users/serializers/profile.py:160 +#: users/forms/profile.py:149 users/serializers/profile.py:76 +#: users/serializers/profile.py:149 users/serializers/profile.py:162 msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" @@ -3677,27 +3687,27 @@ msgstr "用户来源" msgid "Date password last updated" msgstr "最后更新密码日期" -#: users/models/user.py:685 +#: users/models/user.py:692 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:688 +#: users/models/user.py:695 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/serializers/profile.py:32 +#: users/serializers/profile.py:34 msgid "The old password is incorrect" msgstr "旧密码错误" -#: users/serializers/profile.py:40 users/serializers/user.py:112 +#: users/serializers/profile.py:42 users/serializers/user.py:112 msgid "Password does not match security rules" msgstr "密码不满足安全规则" -#: users/serializers/profile.py:46 +#: users/serializers/profile.py:48 msgid "The newly set password is inconsistent" msgstr "两次密码不一致" -#: users/serializers/profile.py:118 users/serializers/user.py:65 +#: users/serializers/profile.py:120 users/serializers/user.py:67 msgid "Is first login" msgstr "首次登录" @@ -3715,58 +3725,58 @@ msgid "Password strategy" msgstr "密码策略" #: users/serializers/user.py:30 -msgid "MFA level for display" -msgstr "多因子认证等级(显示名称)" - -#: users/serializers/user.py:31 -msgid "Login blocked" -msgstr "登录被阻塞" - -#: users/serializers/user.py:32 -msgid "Can update" -msgstr "是否可更新" - -#: users/serializers/user.py:33 -msgid "Can delete" -msgstr "是否可删除" - -#: users/serializers/user.py:35 users/serializers/user.py:72 -msgid "Organization role name" -msgstr "组织角色名称" - -#: users/serializers/user.py:68 -msgid "Avatar url" -msgstr "头像路径" - -#: users/serializers/user.py:70 -msgid "Groups name" -msgstr "用户组名" - -#: users/serializers/user.py:71 -msgid "Source name" -msgstr "用户来源名" - -#: users/serializers/user.py:73 -msgid "Super role name" -msgstr "超级角色名称" - -#: users/serializers/user.py:74 -msgid "Total role name" -msgstr "汇总角色名称" - -#: users/serializers/user.py:75 msgid "MFA enabled" msgstr "是否开启多因子认证" -#: users/serializers/user.py:76 +#: users/serializers/user.py:31 msgid "MFA force enabled" msgstr "强制启用多因子认证" +#: users/serializers/user.py:32 +msgid "MFA level for display" +msgstr "多因子认证等级(显示名称)" + +#: users/serializers/user.py:33 +msgid "Login blocked" +msgstr "登录被阻塞" + +#: users/serializers/user.py:35 +msgid "Can update" +msgstr "是否可更新" + +#: users/serializers/user.py:36 +msgid "Can delete" +msgstr "是否可删除" + +#: users/serializers/user.py:38 users/serializers/user.py:74 +msgid "Organization role name" +msgstr "组织角色名称" + +#: users/serializers/user.py:70 +msgid "Avatar url" +msgstr "头像路径" + +#: users/serializers/user.py:72 +msgid "Groups name" +msgstr "用户组名" + +#: users/serializers/user.py:73 +msgid "Source name" +msgstr "用户来源名" + +#: users/serializers/user.py:75 +msgid "Super role name" +msgstr "超级角色名称" + +#: users/serializers/user.py:76 +msgid "Total role name" +msgstr "汇总角色名称" + #: users/serializers/user.py:100 msgid "Role limit to {}" msgstr "角色只能为 {}" -#: users/serializers/user.py:202 +#: users/serializers/user.py:197 msgid "name not unique" msgstr "名称重复" @@ -4591,19 +4601,19 @@ msgstr "" "
\n" " " -#: users/views/profile/otp.py:193 +#: users/views/profile/otp.py:190 msgid "MFA enable success" msgstr "多因子认证启用成功" -#: users/views/profile/otp.py:194 +#: users/views/profile/otp.py:191 msgid "MFA enable success, return login page" msgstr "多因子认证启用成功,返回到登录页面" -#: users/views/profile/otp.py:196 +#: users/views/profile/otp.py:193 msgid "MFA disable success" msgstr "多因子认证禁用成功" -#: users/views/profile/otp.py:197 +#: users/views/profile/otp.py:194 msgid "MFA disable success, return login page" msgstr "多因子认证禁用成功,返回登录页面" @@ -5098,7 +5108,7 @@ msgstr "许可证导入成功" msgid "License is invalid" msgstr "无效的许可证" -#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:124 +#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:127 msgid "License" msgstr "许可证" @@ -5117,3 +5127,6 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:77 msgid "Community edition" msgstr "社区版" + +#~ msgid "Organization contains undeleted resources" +#~ msgstr "组织包含未删除的资源" diff --git a/apps/orgs/mixins/api.py b/apps/orgs/mixins/api.py index bfcd4b7af..8717d86cd 100644 --- a/apps/orgs/mixins/api.py +++ b/apps/orgs/mixins/api.py @@ -2,6 +2,9 @@ # from rest_framework.viewsets import ModelViewSet, GenericViewSet from rest_framework_bulk import BulkModelViewSet +from rest_framework.exceptions import MethodNotAllowed +from django.utils.translation import ugettext_lazy as _ + from common.mixins import CommonApiMixin, RelationMixin from orgs.utils import current_org @@ -39,15 +42,29 @@ class OrgQuerySetMixin: return queryset -class OrgModelViewSet(CommonApiMixin, OrgQuerySetMixin, ModelViewSet): +class OrgViewSetMixin(OrgQuerySetMixin): + root_org_readonly_msg = _("Root organization only allow view and delete") + + def update(self, request, *args, **kwargs): + if current_org.is_root(): + raise MethodNotAllowed('put', self.root_org_readonly_msg) + return super().update(request, *args, **kwargs) + + def create(self, request, *args, **kwargs): + if current_org.is_root(): + raise MethodNotAllowed('post', self.root_org_readonly_msg) + return super().update(request, *args, **kwargs) + + +class OrgModelViewSet(CommonApiMixin, OrgViewSetMixin, ModelViewSet): pass -class OrgGenericViewSet(CommonApiMixin, OrgQuerySetMixin, GenericViewSet): +class OrgGenericViewSet(CommonApiMixin, OrgViewSetMixin, GenericViewSet): pass -class OrgBulkModelViewSet(CommonApiMixin, OrgQuerySetMixin, BulkModelViewSet): +class OrgBulkModelViewSet(CommonApiMixin, OrgViewSetMixin, BulkModelViewSet): def allow_bulk_destroy(self, qs, filtered): qs_count = qs.count() filtered_count = filtered.count() From f1f5017be33f757ecc7a3616f9962e14d3dd0bba Mon Sep 17 00:00:00 2001 From: xinwen Date: Wed, 17 Mar 2021 15:26:47 +0800 Subject: [PATCH 05/13] =?UTF-8?q?fix:=20=E6=97=A0=E6=95=88=E7=9A=84=20ES?= =?UTF-8?q?=20=E4=BC=9A=E5=8D=A1=E4=BD=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/api/command.py | 15 +++++++++++---- apps/terminal/api/storage.py | 18 ++++++++++++++++++ apps/terminal/backends/command/es.py | 8 ++++---- apps/terminal/exceptions.py | 6 ++++++ apps/terminal/models/storage.py | 10 ++++++++-- 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/apps/terminal/api/command.py b/apps/terminal/api/command.py index 4d7aea9c5..f969e24d7 100644 --- a/apps/terminal/api/command.py +++ b/apps/terminal/api/command.py @@ -11,7 +11,7 @@ from rest_framework.response import Response from rest_framework.decorators import action from django.template import loader -from terminal.models import CommandStorage +from terminal.models import CommandStorage, Command from terminal.filters import CommandFilter from orgs.utils import current_org from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser @@ -19,6 +19,7 @@ from common.const.http import GET from common.utils import get_logger from terminal.utils import send_command_alert_mail from terminal.serializers import InsecureCommandAlertSerializer +from terminal.exceptions import StorageInvalid from ..backends import ( get_command_storage, get_multi_command_storage, SessionCommandSerializer, @@ -116,9 +117,12 @@ class CommandViewSet(viewsets.ModelViewSet): storages = CommandStorage.objects.all() for storage in storages: + if not storage.is_valid(): + continue + qs = storage.get_command_queryset() commands = self.filter_queryset(qs) - merged_commands.extend(commands) + merged_commands.extend(commands[:]) # ES 默认只取 10 条数据 merged_commands.sort(key=lambda command: command.timestamp, reverse=True) page = self.paginate_queryset(merged_commands) @@ -126,7 +130,7 @@ class CommandViewSet(viewsets.ModelViewSet): serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) - serializer = self.get_serializer(queryset, many=True) + serializer = self.get_serializer(merged_commands, many=True) return Response(serializer.data) def list(self, request, *args, **kwargs): @@ -141,7 +145,10 @@ class CommandViewSet(viewsets.ModelViewSet): def get_queryset(self): command_storage_id = self.request.query_params.get('command_storage_id') storage = CommandStorage.objects.get(id=command_storage_id) - qs = storage.get_command_queryset() + if not storage.is_valid(): + raise StorageInvalid + else: + qs = storage.get_command_queryset() return qs def create(self, request, *args, **kwargs): diff --git a/apps/terminal/api/storage.py b/apps/terminal/api/storage.py index a7c05adca..4aa3fecbb 100644 --- a/apps/terminal/api/storage.py +++ b/apps/terminal/api/storage.py @@ -46,7 +46,13 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet): def tree(self, request: Request): storage_qs = self.get_queryset().exclude(name='null') storages_with_count = [] + invalid_storages = [] + for storage in storage_qs: + if not storage.is_valid(): + invalid_storages.append(storage) + continue + command_qs = storage.get_command_queryset() filterset = CommandFilter( data=request.query_params, queryset=command_qs, @@ -70,6 +76,7 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet): 'open': True, } + invalid = _('Invalid') nodes = [ { 'id': storage.id, @@ -78,7 +85,18 @@ class CommandStorageViewSet(BaseStorageViewSetMixin, viewsets.ModelViewSet): 'pId': 'root', 'isParent': False, 'open': False, + 'valid': True, } for storage, command_count in storages_with_count + ] + [ + { + 'id': storage.id, + 'name': f'{storage.name}({storage.type}) *{invalid}', + 'title': f'{storage.name}({storage.type})', + 'pId': 'root', + 'isParent': False, + 'open': False, + 'valid': False, + } for storage in invalid_storages ] nodes.append(root) return Response(data=nodes) diff --git a/apps/terminal/backends/command/es.py b/apps/terminal/backends/command/es.py index da51c44e2..5c880a120 100644 --- a/apps/terminal/backends/command/es.py +++ b/apps/terminal/backends/command/es.py @@ -25,7 +25,7 @@ class CommandStore(): kwargs = config.get("OTHER", {}) self.index = config.get("INDEX") or 'jumpserver' self.doc_type = config.get("DOC_TYPE") or 'command_store' - self.es = Elasticsearch(hosts=hosts, **kwargs) + self.es = Elasticsearch(hosts=hosts, max_retries=0, **kwargs) @staticmethod def make_data(command): @@ -81,9 +81,9 @@ class CommandStore(): """返回所有数据""" raise NotImplementedError("Not support") - def ping(self): + def ping(self, timeout=None): try: - return self.es.ping() + return self.es.ping(request_timeout=timeout) except Exception: return False @@ -256,7 +256,7 @@ class QuerySet(DJQuerySet): clone = self.__clone() from_ = item.start or 0 if item.stop is None: - size = 10 + size = self.max_result_window - from_ else: size = item.stop - from_ diff --git a/apps/terminal/exceptions.py b/apps/terminal/exceptions.py index a3b63a3e9..bb3e43591 100644 --- a/apps/terminal/exceptions.py +++ b/apps/terminal/exceptions.py @@ -6,3 +6,9 @@ from common.exceptions import JMSException class BulkCreateNotSupport(JMSException): default_code = 'bulk_create_not_support' default_detail = _('Bulk create not support') + + +class StorageInvalid(JMSException): + default_code = 'storage_invalid' + default_detail = _('Storage is invalid') + diff --git a/apps/terminal/models/storage.py b/apps/terminal/models/storage.py index 9497ea802..4826e2eef 100644 --- a/apps/terminal/models/storage.py +++ b/apps/terminal/models/storage.py @@ -52,8 +52,14 @@ class CommandStorage(CommonModelMixin): def is_valid(self): if self.type_null_or_server: return True - storage = jms_storage.get_log_storage(self.config) - return storage.ping() + + if self.type not in TYPE_ENGINE_MAPPING: + logger.error(f'Command storage `{self.type}` not support') + return False + + engine_mod = import_module(TYPE_ENGINE_MAPPING[self.type]) + store = engine_mod.CommandStore(self.config) + return store.ping(timeout=3) def is_use(self): return Terminal.objects.filter(command_storage=self.name, is_deleted=False).exists() From 50c89431df1b8b8fb0a8bfd273ab569a160447e6 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 17 Mar 2021 14:12:42 +0800 Subject: [PATCH 06/13] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8Dansible=20summa?= =?UTF-8?q?ry=E6=98=BE=E7=A4=BA=E4=B8=A4=E9=81=8D=E7=9A=84=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/ops/ansible/display.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/ops/ansible/display.py b/apps/ops/ansible/display.py index b272f6a6d..0c4d57788 100644 --- a/apps/ops/ansible/display.py +++ b/apps/ops/ansible/display.py @@ -53,7 +53,7 @@ class AdHocDisplay(Display, metaclass=UnSingleton): # 这里先不 flush,log 文件不需要那么及时。 self.log_file.write(msg) - def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False): + def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False, newline=True): if color: msg = stringc(msg, color) @@ -62,5 +62,7 @@ class AdHocDisplay(Display, metaclass=UnSingleton): else: msg2 = msg - self._write_to_screen(msg2, stderr) - self._write_to_log_file(msg2) + if log_only: + self._write_to_log_file(msg2) + else: + self._write_to_screen(msg2, stderr) From 42afc1e0bf3257f7a1a11f8526d8581e58874418 Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 17 Mar 2021 15:04:34 +0800 Subject: [PATCH 07/13] =?UTF-8?q?fix(perms):=20=E4=BF=AE=E5=A4=8D=E5=88=A0?= =?UTF-8?q?=E9=99=A4=20=E8=B5=84=E4=BA=A7=E6=88=96=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E5=BC=95=E8=B5=B7=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../signals_handler/node_assets_amount.py | 21 +++--- apps/perms/signals_handler/refresh_perms.py | 67 ++++++++++++------- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/apps/assets/signals_handler/node_assets_amount.py b/apps/assets/signals_handler/node_assets_amount.py index 4501d0226..cb9d2fcc1 100644 --- a/apps/assets/signals_handler/node_assets_amount.py +++ b/apps/assets/signals_handler/node_assets_amount.py @@ -7,7 +7,7 @@ from django.db.models.signals import ( m2m_changed ) -from orgs.utils import ensure_in_real_or_default_org +from orgs.utils import ensure_in_real_or_default_org, tmp_to_org from common.const.signals import PRE_ADD, POST_REMOVE, PRE_CLEAR from common.utils import get_logger from assets.models import Asset, Node, compute_parent_key @@ -34,15 +34,16 @@ def on_node_asset_change(sender, action, instance, reverse, pk_set, **kwargs): operator = mapper[action] - if reverse: - node: Node = instance - asset_pk_set = set(pk_set) - NodeAssetsAmountUtils.update_node_assets_amount(node, asset_pk_set, operator) - else: - asset_pk = instance.id - # 与资产直接关联的节点 - node_keys = set(Node.objects.filter(id__in=pk_set).values_list('key', flat=True)) - NodeAssetsAmountUtils.update_nodes_asset_amount(node_keys, asset_pk, operator) + with tmp_to_org(instance.org): + if reverse: + node: Node = instance + asset_pk_set = set(pk_set) + NodeAssetsAmountUtils.update_node_assets_amount(node, asset_pk_set, operator) + else: + asset_pk = instance.id + # 与资产直接关联的节点 + node_keys = set(Node.objects.filter(id__in=pk_set).values_list('key', flat=True)) + NodeAssetsAmountUtils.update_nodes_asset_amount(node_keys, asset_pk, operator) class NodeAssetsAmountUtils: diff --git a/apps/perms/signals_handler/refresh_perms.py b/apps/perms/signals_handler/refresh_perms.py index d91594444..1cd0332e7 100644 --- a/apps/perms/signals_handler/refresh_perms.py +++ b/apps/perms/signals_handler/refresh_perms.py @@ -5,7 +5,7 @@ from django.dispatch import receiver from users.models import User from assets.models import Asset -from orgs.utils import current_org +from orgs.utils import current_org, tmp_to_org from common.utils import get_logger from common.exceptions import M2MReverseNotAllowed from common.const.signals import POST_ADD, POST_REMOVE, POST_CLEAR @@ -18,24 +18,28 @@ logger = get_logger(__file__) @receiver(m2m_changed, sender=User.groups.through) def on_user_groups_change(sender, instance, action, reverse, pk_set, **kwargs): - if action.startswith('post'): - if reverse: - group_ids = [instance.id] - user_ids = pk_set - else: - group_ids = pk_set - user_ids = [instance.id] + if not action.startswith('post'): + return + if reverse: + group_ids = [instance.id] + user_ids = pk_set + else: + group_ids = pk_set + user_ids = [instance.id] - exists = AssetPermission.user_groups.through.objects.filter(usergroup_id__in=group_ids).exists() - if exists: - org_ids = [current_org.id] - UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(org_ids, user_ids) + exists = AssetPermission.user_groups.through.objects.filter(usergroup_id__in=group_ids).exists() + if not exists: + return + with tmp_to_org(instance.org): + org_ids = [current_org.id] + UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users(org_ids, user_ids) @receiver([pre_delete], sender=AssetPermission) def on_asset_perm_pre_delete(sender, instance, **kwargs): # 授权删除之前,查出所有相关用户 - UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id]) + with tmp_to_org(instance.org): + UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id]) @receiver([pre_save], sender=AssetPermission) @@ -44,14 +48,17 @@ def on_asset_perm_pre_save(sender, instance, **kwargs): old = AssetPermission.objects.get(id=instance.id) if old.is_valid != instance.is_valid: - UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id]) + with tmp_to_org(instance.org): + UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id]) except AssetPermission.DoesNotExist: pass @receiver([post_save], sender=AssetPermission) def on_asset_perm_post_save(sender, instance, created, **kwargs): - if created: + if not created: + return + with tmp_to_org(instance.org): UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id]) @@ -64,7 +71,10 @@ def on_permission_nodes_changed(sender, instance, action, reverse, **kwargs): if reverse: raise M2MReverseNotAllowed - if need_rebuild_mapping_node(action): + if not need_rebuild_mapping_node(action): + return + + with tmp_to_org(instance.org): UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id]) @@ -73,28 +83,38 @@ def on_permission_assets_changed(sender, instance, action, reverse, pk_set, mode if reverse: raise M2MReverseNotAllowed - if need_rebuild_mapping_node(action): + if not need_rebuild_mapping_node(action): + return + with tmp_to_org(instance.org): UserGrantedTreeRefreshController.add_need_refresh_by_asset_perm_ids([instance.id]) @receiver(m2m_changed, sender=AssetPermission.users.through) -def on_asset_permission_users_changed(sender, action, reverse, pk_set, **kwargs): +def on_asset_permission_users_changed(sender, action, reverse, instance, pk_set, **kwargs): if reverse: raise M2MReverseNotAllowed - if need_rebuild_mapping_node(action): + if not need_rebuild_mapping_node(action): + return + + with tmp_to_org(instance.org): UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users( [current_org.id], pk_set ) @receiver(m2m_changed, sender=AssetPermission.user_groups.through) -def on_asset_permission_user_groups_changed(sender, action, pk_set, reverse, **kwargs): +def on_asset_permission_user_groups_changed(sender, instance, action, pk_set, reverse, **kwargs): if reverse: raise M2MReverseNotAllowed - if need_rebuild_mapping_node(action): - user_ids = User.groups.through.objects.filter(usergroup_id__in=pk_set).distinct().values_list('user_id', flat=True) + if not need_rebuild_mapping_node(action): + return + + user_ids = User.groups.through.objects.filter(usergroup_id__in=pk_set) \ + .values_list('user_id', flat=True) \ + .distinct() + with tmp_to_org(instance.org): UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users( [current_org.id], user_ids ) @@ -112,4 +132,5 @@ def on_node_asset_change(action, instance, reverse, pk_set, **kwargs): asset_pk_set = [instance.id] node_pk_set = pk_set - UserGrantedTreeRefreshController.add_need_refresh_on_nodes_assets_relate_change(node_pk_set, asset_pk_set) + with tmp_to_org(instance.org): + UserGrantedTreeRefreshController.add_need_refresh_on_nodes_assets_relate_change(node_pk_set, asset_pk_set) From fd3a4d887e782ec1dc563a7ab26b551bc6945d0e Mon Sep 17 00:00:00 2001 From: xinwen Date: Wed, 17 Mar 2021 16:51:40 +0800 Subject: [PATCH 08/13] =?UTF-8?q?fix:=20Root=20=E7=BB=84=E7=BB=87=E6=9F=A5?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E5=91=BD=E4=BB=A4=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/backends/command/es.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/terminal/backends/command/es.py b/apps/terminal/backends/command/es.py index 5c880a120..009435a5b 100644 --- a/apps/terminal/backends/command/es.py +++ b/apps/terminal/backends/command/es.py @@ -121,7 +121,11 @@ class CommandStore(): org_id = match.get('org_id') real_default_org_id = '00000000-0000-0000-0000-000000000002' - if org_id in (real_default_org_id, ''): + root_org_id = '00000000-0000-0000-0000-000000000000' + + if org_id == root_org_id: + match.pop('org_id') + elif org_id in (real_default_org_id, ''): match.pop('org_id') should.append({ 'bool':{ From c55e2db75e370d1fb1e4f336a467c9e16d6a169e Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 17 Mar 2021 17:08:49 +0800 Subject: [PATCH 09/13] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96license?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/utils.py | 9 +++++++++ apps/settings/api/common.py | 11 ++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/jumpserver/utils.py b/apps/jumpserver/utils.py index 72a836892..d19d950e2 100644 --- a/apps/jumpserver/utils.py +++ b/apps/jumpserver/utils.py @@ -2,6 +2,8 @@ # from functools import partial from werkzeug.local import LocalProxy + +from django.conf import settings from common.local import thread_local @@ -17,4 +19,11 @@ def get_current_request(): return _find('current_request') +def has_valid_xpack_license(): + if not settings.XPACK_ENABLED: + return False + from xpack.plugins.license.models import License + return License.has_valid_license() + + current_request = LocalProxy(partial(_find, 'current_request')) diff --git a/apps/settings/api/common.py b/apps/settings/api/common.py index 04674d25b..8aafee063 100644 --- a/apps/settings/api/common.py +++ b/apps/settings/api/common.py @@ -10,6 +10,7 @@ from django.core.mail import send_mail, get_connection from django.utils.translation import ugettext_lazy as _ from django.templatetags.static import static +from jumpserver.utils import has_valid_xpack_license from common.permissions import IsSuperUser from common.utils import get_logger from .. import serializers @@ -94,14 +95,6 @@ class PublicSettingApi(generics.RetrieveAPIView): logo_urls.update({attr: getattr(obj, attr).url}) return logo_urls - @staticmethod - def get_xpack_license_is_valid(): - if not settings.XPACK_ENABLED: - return False - - from xpack.plugins.license.models import License - return License.has_valid_license() - @staticmethod def get_login_title(): default_title = _('Welcome to the JumpServer open source Bastion Host') @@ -121,7 +114,7 @@ class PublicSettingApi(generics.RetrieveAPIView): "SECURITY_MFA_VERIFY_TTL": settings.SECURITY_MFA_VERIFY_TTL, "SECURITY_COMMAND_EXECUTION": settings.SECURITY_COMMAND_EXECUTION, "SECURITY_PASSWORD_EXPIRATION_TIME": settings.SECURITY_PASSWORD_EXPIRATION_TIME, - "XPACK_LICENSE_IS_VALID": self.get_xpack_license_is_valid(), + "XPACK_LICENSE_IS_VALID": has_valid_xpack_license(), "LOGIN_TITLE": self.get_login_title(), "LOGO_URLS": self.get_logo_urls(), "TICKETS_ENABLED": settings.TICKETS_ENABLED, From dfa2f7d6c91544827a45930ac88a5f21726cac8c Mon Sep 17 00:00:00 2001 From: Bai Date: Wed, 17 Mar 2021 14:17:53 +0800 Subject: [PATCH 10/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=99=BB=E5=BD=95=E5=A4=8D=E6=A0=B8=E5=B7=A5=E5=8D=95?= =?UTF-8?q?org=5Fid=E4=B8=BAROOT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/models.py | 2 ++ apps/authentication/views/login.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/authentication/models.py b/apps/authentication/models.py index 5764e84c8..f4db736af 100644 --- a/apps/authentication/models.py +++ b/apps/authentication/models.py @@ -68,6 +68,7 @@ class LoginConfirmSetting(CommonModelMixin): def create_confirm_ticket(self, request=None): from tickets import const from tickets.models import Ticket + from orgs.models import Organization ticket_title = _('Login confirm') + ' {}'.format(self.user) ticket_meta = self.construct_confirm_ticket_meta(request) ticket_assignees = self.reviewers.all() @@ -75,6 +76,7 @@ class LoginConfirmSetting(CommonModelMixin): 'title': ticket_title, 'type': const.TicketTypeChoices.login_confirm.value, 'meta': ticket_meta, + 'org_id': Organization.ROOT_ID, } ticket = Ticket.objects.create(**data) ticket.assignees.set(ticket_assignees) diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py index 2c86970d9..6b0e799b2 100644 --- a/apps/authentication/views/login.py +++ b/apps/authentication/views/login.py @@ -170,7 +170,7 @@ class UserLoginWaitConfirmView(TemplateView): if not ticket_id: ticket = None else: - ticket = get_object_or_none(Ticket, pk=ticket_id) + ticket = Ticket.all().filter(pk=ticket_id).first() context = super().get_context_data(**kwargs) if ticket: timestamp_created = datetime.datetime.timestamp(ticket.date_created) From 6ad1362a3f027ccf35ba0c6cdee90da1c8e57024 Mon Sep 17 00:00:00 2001 From: xinwen Date: Wed, 17 Mar 2021 18:09:38 +0800 Subject: [PATCH 11/13] =?UTF-8?q?perf:=20=E6=89=B9=E9=87=8F=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=97=A5=E5=BF=97=E5=AF=BC=E5=87=BA=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20hosts=5Fdisplay=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/audits/serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/audits/serializers.py b/apps/audits/serializers.py index b94ffa8c9..f90c2962b 100644 --- a/apps/audits/serializers.py +++ b/apps/audits/serializers.py @@ -64,6 +64,7 @@ class SessionAuditSerializer(serializers.ModelSerializer): class CommandExecutionSerializer(serializers.ModelSerializer): is_success = serializers.BooleanField(read_only=True, label=_('Is success')) + hosts_display = serializers.ListSerializer(child=serializers.CharField(), source='hosts', read_only=True) class Meta: model = CommandExecution @@ -72,7 +73,7 @@ class CommandExecutionSerializer(serializers.ModelSerializer): 'run_as', 'command', 'user', 'is_finished', 'date_start', 'result', 'is_success', 'org_id' ] - fields = fields_small + ['hosts', 'run_as_display', 'user_display'] + fields = fields_small + ['hosts', 'hosts_display', 'run_as_display', 'user_display'] extra_kwargs = { 'result': {'label': _('Result')}, # model 上的方法,只能在这修改 'is_success': {'label': _('Is success')}, From dba9550bc0f49fb1b6aae248993f20cc8244915c Mon Sep 17 00:00:00 2001 From: Bai Date: Wed, 17 Mar 2021 18:21:00 +0800 Subject: [PATCH 12/13] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/audits/serializers.py | 4 +- apps/locale/zh/LC_MESSAGES/django.mo | Bin 73608 -> 73533 bytes apps/locale/zh/LC_MESSAGES/django.po | 168 ++++++++++++++------------- 3 files changed, 92 insertions(+), 80 deletions(-) diff --git a/apps/audits/serializers.py b/apps/audits/serializers.py index f90c2962b..74eebbecc 100644 --- a/apps/audits/serializers.py +++ b/apps/audits/serializers.py @@ -64,7 +64,9 @@ class SessionAuditSerializer(serializers.ModelSerializer): class CommandExecutionSerializer(serializers.ModelSerializer): is_success = serializers.BooleanField(read_only=True, label=_('Is success')) - hosts_display = serializers.ListSerializer(child=serializers.CharField(), source='hosts', read_only=True) + hosts_display = serializers.ListSerializer( + child=serializers.CharField(), source='hosts', read_only=True, label=_('Hosts for display') + ) class Meta: model = CommandExecution diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 2d48fa05da7d6fc58eb85afdc6a41a318e6a0aef..27ceba4a14bed95c12f3d5c37663ff95be4c418a 100644 GIT binary patch delta 20983 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 DDU|HQ diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 4bcdd69e4..65696ffa0 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-03-17 11:21+0800\n" +"POT-Creation-Date: 2021-03-17 18:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -35,7 +35,7 @@ msgstr "" #: assets/models/cmd_filter.py:21 assets/models/domain.py:21 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: orgs/models.py:23 perms/models/base.py:49 settings/models.py:29 -#: terminal/models/storage.py:23 terminal/models/storage.py:75 +#: terminal/models/storage.py:23 terminal/models/storage.py:81 #: terminal/models/task.py:16 terminal/models/terminal.py:139 #: users/forms/profile.py:32 users/models/group.py:15 users/models/user.py:530 #: users/templates/users/_select_user_modal.html:13 @@ -56,12 +56,12 @@ msgid "Name" msgstr "名称" #: acls/models/base.py:27 assets/models/cmd_filter.py:53 -#: assets/models/user.py:119 +#: assets/models/user.py:122 msgid "Priority" msgstr "优先级" #: acls/models/base.py:28 assets/models/cmd_filter.py:53 -#: assets/models/user.py:119 +#: assets/models/user.py:122 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" @@ -82,7 +82,7 @@ msgstr "激活中" #: assets/models/domain.py:22 assets/models/domain.py:56 #: assets/models/group.py:23 assets/models/label.py:23 ops/models/adhoc.py:37 #: orgs/models.py:26 perms/models/base.py:57 settings/models.py:34 -#: terminal/models/storage.py:29 terminal/models/storage.py:81 +#: terminal/models/storage.py:29 terminal/models/storage.py:87 #: terminal/models/terminal.py:153 tickets/models/ticket.py:73 #: users/models/group.py:16 users/models/user.py:563 #: users/templates/users/user_detail.html:115 @@ -125,13 +125,13 @@ msgstr "动作" #: acls/models/login_acl.py:28 acls/models/login_asset_acl.py:20 #: acls/serializers/login_acl.py:28 assets/models/label.py:15 #: audits/models.py:36 audits/models.py:56 audits/models.py:69 -#: audits/serializers.py:81 authentication/models.py:44 -#: authentication/models.py:95 orgs/models.py:18 orgs/models.py:420 +#: audits/serializers.py:84 authentication/models.py:44 +#: authentication/models.py:97 orgs/models.py:18 orgs/models.py:417 #: perms/models/base.py:50 templates/index.html:78 #: terminal/backends/command/models.py:18 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:37 #: tickets/models/comment.py:17 users/models/user.py:159 -#: users/models/user.py:684 users/serializers/group.py:20 +#: users/models/user.py:699 users/serializers/group.py:20 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -144,7 +144,7 @@ msgstr "动作" msgid "User" msgstr "用户" -#: acls/models/login_asset_acl.py:17 authentication/models.py:71 +#: acls/models/login_asset_acl.py:17 authentication/models.py:72 #: tickets/const.py:9 users/templates/users/user_detail.html:250 msgid "Login confirm" msgstr "登录复核" @@ -228,7 +228,7 @@ msgid "Hostname" msgstr "主机名" #: acls/serializers/login_asset_acl.py:41 assets/models/asset.py:187 -#: assets/models/domain.py:54 assets/models/user.py:120 +#: assets/models/domain.py:54 assets/models/user.py:123 #: terminal/serializers/session.py:29 terminal/serializers/storage.py:69 msgid "Protocol" msgstr "协议" @@ -279,7 +279,7 @@ msgstr "类别" #: perms/models/application_permission.py:23 #: perms/serializers/application/permission.py:17 #: perms/serializers/application/user_permission.py:34 -#: terminal/models/storage.py:26 terminal/models/storage.py:78 +#: terminal/models/storage.py:26 terminal/models/storage.py:84 #: tickets/models/ticket.py:38 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:27 #: users/templates/users/user_granted_database_app.html:35 @@ -413,7 +413,7 @@ msgstr "系统平台" msgid "Protocols" msgstr "协议组" -#: assets/models/asset.py:192 assets/models/user.py:115 +#: assets/models/asset.py:192 assets/models/user.py:118 #: perms/models/asset_permission.py:100 #: xpack/plugins/change_auth_plan/models.py:56 #: xpack/plugins/gathered_user/models.py:24 @@ -504,7 +504,7 @@ msgstr "标签管理" #: assets/models/cluster.py:28 assets/models/cmd_filter.py:26 #: assets/models/cmd_filter.py:60 assets/models/group.py:21 #: common/db/models.py:70 common/mixins/models.py:49 orgs/models.py:24 -#: orgs/models.py:424 perms/models/base.py:55 users/models/user.py:571 +#: orgs/models.py:421 perms/models/base.py:55 users/models/user.py:571 #: users/serializers/group.py:35 users/templates/users/user_detail.html:97 #: xpack/plugins/change_auth_plan/models.py:81 #: xpack/plugins/cloud/models.py:104 xpack/plugins/gathered_user/models.py:30 @@ -518,7 +518,7 @@ msgstr "创建者" #: assets/models/gathered_user.py:19 assets/models/group.py:22 #: assets/models/label.py:25 common/db/models.py:72 common/mixins/models.py:50 #: ops/models/adhoc.py:38 ops/models/command.py:29 orgs/models.py:25 -#: orgs/models.py:422 perms/models/base.py:56 users/models/group.py:18 +#: orgs/models.py:419 perms/models/base.py:56 users/models/group.py:18 #: users/templates/users/user_group_detail.html:58 #: xpack/plugins/cloud/models.py:107 msgid "Date created" @@ -554,7 +554,7 @@ msgstr "SSH公钥" #: assets/models/base.py:257 assets/models/gathered_user.py:20 #: common/db/models.py:73 common/mixins/models.py:51 ops/models/adhoc.py:39 -#: orgs/models.py:423 +#: orgs/models.py:420 msgid "Date updated" msgstr "更新日期" @@ -592,7 +592,7 @@ msgid "Default" msgstr "默认" #: assets/models/cluster.py:36 assets/models/label.py:14 -#: users/models/user.py:696 +#: users/models/user.py:711 msgid "System" msgstr "系统" @@ -600,7 +600,7 @@ msgstr "系统" msgid "Default Cluster" msgstr "默认Cluster" -#: assets/models/cmd_filter.py:33 assets/models/user.py:125 +#: assets/models/cmd_filter.py:33 assets/models/user.py:128 msgid "Command filter" msgstr "命令过滤器" @@ -665,7 +665,7 @@ msgstr "资产组" msgid "Default asset group" msgstr "默认资产组" -#: assets/models/label.py:19 assets/models/node.py:601 settings/models.py:30 +#: assets/models/label.py:19 assets/models/node.py:538 settings/models.py:30 msgid "Value" msgstr "值" @@ -677,19 +677,19 @@ msgstr "新节点" msgid "empty" msgstr "空" -#: assets/models/node.py:600 perms/models/asset_permission.py:156 +#: assets/models/node.py:537 perms/models/asset_permission.py:156 msgid "Key" msgstr "键" -#: assets/models/node.py:602 +#: assets/models/node.py:539 msgid "Full value" msgstr "全称" -#: assets/models/node.py:605 perms/models/asset_permission.py:157 +#: assets/models/node.py:542 perms/models/asset_permission.py:157 msgid "Parent key" msgstr "ssh私钥" -#: assets/models/node.py:614 assets/serializers/system_user.py:191 +#: assets/models/node.py:551 assets/serializers/system_user.py:191 #: users/templates/users/user_asset_permission.html:41 #: users/templates/users/user_asset_permission.html:73 #: users/templates/users/user_asset_permission.html:158 @@ -697,66 +697,66 @@ msgstr "ssh私钥" msgid "Node" msgstr "节点" -#: assets/models/user.py:111 +#: assets/models/user.py:114 msgid "Automatic login" msgstr "自动登录" -#: assets/models/user.py:112 +#: assets/models/user.py:115 msgid "Manually login" msgstr "手动登录" -#: assets/models/user.py:114 +#: assets/models/user.py:117 msgid "Username same with user" msgstr "用户名与用户相同" -#: assets/models/user.py:116 assets/serializers/domain.py:30 +#: assets/models/user.py:119 assets/serializers/domain.py:30 #: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:52 msgid "Assets" msgstr "资产" -#: assets/models/user.py:117 templates/_nav.html:17 +#: assets/models/user.py:120 templates/_nav.html:17 #: users/views/profile/password.py:42 users/views/profile/pubkey.py:36 msgid "Users" msgstr "用户管理" -#: assets/models/user.py:118 users/templates/users/user_group_list.html:90 +#: assets/models/user.py:121 users/templates/users/user_group_list.html:90 #: users/templates/users/user_profile.html:124 msgid "User groups" msgstr "用户组" -#: assets/models/user.py:121 +#: assets/models/user.py:124 msgid "Auto push" msgstr "自动推送" -#: assets/models/user.py:122 +#: assets/models/user.py:125 msgid "Sudo" msgstr "Sudo" -#: assets/models/user.py:123 +#: assets/models/user.py:126 msgid "Shell" msgstr "Shell" -#: assets/models/user.py:124 +#: assets/models/user.py:127 msgid "Login mode" msgstr "登录模式" -#: assets/models/user.py:126 +#: assets/models/user.py:129 msgid "SFTP Root" msgstr "SFTP根路径" -#: assets/models/user.py:127 authentication/models.py:93 +#: assets/models/user.py:130 authentication/models.py:95 msgid "Token" msgstr "" -#: assets/models/user.py:128 +#: assets/models/user.py:131 msgid "Home" msgstr "家目录" -#: assets/models/user.py:129 +#: assets/models/user.py:132 msgid "System groups" msgstr "用户组" -#: assets/models/user.py:221 audits/models.py:39 +#: assets/models/user.py:228 audits/models.py:39 #: perms/models/application_permission.py:31 #: perms/models/asset_permission.py:101 templates/_nav.html:45 #: terminal/backends/command/models.py:20 @@ -1015,17 +1015,11 @@ msgstr "资产已经被禁用, 跳过: {}" msgid "Asset may not be support ansible, skipped: {}" msgstr "资产或许不支持ansible, 跳过: {}" -#: assets/tasks/utils.py:29 -msgid "" -"Push system user task skip, auto push not enable or protocol is not ssh or " -"rdp: {}" -msgstr "推送系统用户任务跳过,自动推送没有打开,或协议不是ssh或rdp: {}" - -#: assets/tasks/utils.py:36 +#: assets/tasks/utils.py:39 msgid "For security, do not push user {}" msgstr "为了安全,禁止推送用户 {}" -#: assets/tasks/utils.py:56 +#: assets/tasks/utils.py:55 msgid "No assets matched, stop task" msgstr "没有匹配到资产,结束任务" @@ -1172,7 +1166,7 @@ msgstr "用户代理" #: authentication/templates/authentication/_mfa_confirm_modal.html:14 #: authentication/templates/authentication/login_otp.html:6 #: users/forms/profile.py:64 users/models/user.py:552 -#: users/serializers/profile.py:104 users/templates/users/user_detail.html:77 +#: users/serializers/profile.py:99 users/templates/users/user_detail.html:77 #: users/templates/users/user_profile.html:87 msgid "MFA" msgstr "多因子认证" @@ -1211,29 +1205,33 @@ msgstr "状态(显示名称)" msgid "MFA for display" msgstr "多因子认证状态(显示名称)" -#: audits/serializers.py:66 audits/serializers.py:78 ops/models/adhoc.py:247 +#: audits/serializers.py:66 audits/serializers.py:81 ops/models/adhoc.py:247 #: terminal/serializers/session.py:34 msgid "Is success" msgstr "是否成功" -#: audits/serializers.py:77 ops/models/command.py:26 +#: audits/serializers.py:68 +msgid "Hosts for display" +msgstr "主机 (显示名称)" + +#: audits/serializers.py:80 ops/models/command.py:26 #: xpack/plugins/cloud/models.py:155 msgid "Result" msgstr "结果" -#: audits/serializers.py:79 terminal/serializers/storage.py:178 +#: audits/serializers.py:82 terminal/serializers/storage.py:178 msgid "Hosts" msgstr "主机" -#: audits/serializers.py:80 +#: audits/serializers.py:83 msgid "Run as" msgstr "运行用户" -#: audits/serializers.py:82 +#: audits/serializers.py:85 msgid "Run as for display" msgstr "运行用户(显示名称)" -#: audits/serializers.py:83 +#: audits/serializers.py:86 msgid "User for display" msgstr "用户(显示名称)" @@ -1406,7 +1404,7 @@ msgstr "多因子认证验证码" msgid "Private Token" msgstr "SSH密钥" -#: authentication/models.py:94 +#: authentication/models.py:96 msgid "Expired" msgstr "过期时间" @@ -1436,7 +1434,7 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: users/models/user.py:445 users/serializers/profile.py:101 +#: users/models/user.py:445 users/serializers/profile.py:96 #: users/templates/users/user_profile.html:94 #: users/templates/users/user_profile.html:163 #: users/templates/users/user_profile.html:166 @@ -1445,7 +1443,7 @@ msgid "Disable" msgstr "禁用" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:446 users/serializers/profile.py:102 +#: users/models/user.py:446 users/serializers/profile.py:97 #: users/templates/users/user_profile.html:92 #: users/templates/users/user_profile.html:170 msgid "Enable" @@ -1886,7 +1884,7 @@ msgid "Root organization only allow view and delete" msgstr "全局组织仅支持 查看和删除" #: orgs/mixins/models.py:45 orgs/mixins/serializers.py:25 orgs/models.py:36 -#: orgs/models.py:419 orgs/serializers.py:101 +#: orgs/models.py:416 orgs/serializers.py:101 #: tickets/serializers/ticket/ticket.py:81 msgid "Organization" msgstr "组织" @@ -1903,7 +1901,7 @@ msgstr "组织审计员" msgid "GLOBAL" msgstr "全局组织" -#: orgs/models.py:421 users/models/user.py:540 +#: orgs/models.py:418 users/models/user.py:540 #: users/templates/users/_select_user_modal.html:15 #: users/templates/users/user_detail.html:73 #: users/templates/users/user_list.html:16 @@ -1911,14 +1909,6 @@ msgstr "全局组织" msgid "Role" msgstr "角色" -#: perms/const.py:7 perms/models/asset_permission.py:189 -msgid "Ungrouped" -msgstr "未分组" - -#: perms/const.py:10 -msgid "Empty" -msgstr "空" - #: perms/exceptions.py:9 msgid "The administrator is modifying permissions. Please wait" msgstr "管理员正在修改授权,请稍等" @@ -1977,6 +1967,10 @@ msgstr "动作" msgid "Asset permission" msgstr "资产授权" +#: perms/models/asset_permission.py:189 +msgid "Ungrouped" +msgstr "未分组" + #: perms/models/asset_permission.py:191 msgid "Favorite" msgstr "收藏夹" @@ -2032,11 +2026,11 @@ msgstr "用户组数量" msgid "System users amount" msgstr "系统用户数量" -#: settings/api/common.py:24 +#: settings/api/common.py:25 msgid "Test mail sent to {}, please check" msgstr "邮件已经发送{}, 请检查" -#: settings/api/common.py:107 xpack/plugins/interface/api.py:18 +#: settings/api/common.py:100 xpack/plugins/interface/api.py:18 #: xpack/plugins/interface/models.py:36 msgid "Welcome to the JumpServer open source Bastion Host" msgstr "欢迎使用JumpServer开源堡垒机" @@ -2924,19 +2918,23 @@ msgstr "不允许删除默认存储配置" msgid "Cannot delete storage that is being used" msgstr "不允许删除正在使用的存储配置" -#: terminal/api/storage.py:66 terminal/api/storage.py:67 +#: terminal/api/storage.py:72 terminal/api/storage.py:73 msgid "Command storages" msgstr "命令存储" -#: terminal/api/storage.py:104 +#: terminal/api/storage.py:79 +msgid "Invalid" +msgstr "无效" + +#: terminal/api/storage.py:122 msgid "Test failure: {}" msgstr "测试失败: {}" -#: terminal/api/storage.py:107 +#: terminal/api/storage.py:125 msgid "Test successful" msgstr "测试成功" -#: terminal/api/storage.py:109 +#: terminal/api/storage.py:127 msgid "Test failure: Account invalid" msgstr "测试失败: 账户无效" @@ -2997,6 +2995,10 @@ msgstr "正常" msgid "Bulk create not support" msgstr "不支持批量创建" +#: terminal/exceptions.py:13 +msgid "Storage is invalid" +msgstr "存储无效" + #: terminal/models/session.py:43 msgid "Login from" msgstr "登录来源" @@ -3648,8 +3650,8 @@ msgstr "复制你的公钥到这里" msgid "Public key should not be the same as your old one." msgstr "不能和原来的密钥相同" -#: users/forms/profile.py:149 users/serializers/profile.py:76 -#: users/serializers/profile.py:149 users/serializers/profile.py:162 +#: users/forms/profile.py:149 users/serializers/profile.py:71 +#: users/serializers/profile.py:144 users/serializers/profile.py:157 msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" @@ -3687,27 +3689,27 @@ msgstr "用户来源" msgid "Date password last updated" msgstr "最后更新密码日期" -#: users/models/user.py:692 +#: users/models/user.py:707 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:695 +#: users/models/user.py:710 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/serializers/profile.py:34 +#: users/serializers/profile.py:29 msgid "The old password is incorrect" msgstr "旧密码错误" -#: users/serializers/profile.py:42 users/serializers/user.py:112 +#: users/serializers/profile.py:37 users/serializers/user.py:112 msgid "Password does not match security rules" msgstr "密码不满足安全规则" -#: users/serializers/profile.py:48 +#: users/serializers/profile.py:43 msgid "The newly set password is inconsistent" msgstr "两次密码不一致" -#: users/serializers/profile.py:120 users/serializers/user.py:67 +#: users/serializers/profile.py:115 users/serializers/user.py:67 msgid "Is first login" msgstr "首次登录" @@ -5128,5 +5130,13 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "" +#~ "Push system user task skip, auto push not enable or protocol is not ssh " +#~ "or rdp: {}" +#~ msgstr "推送系统用户任务跳过,自动推送没有打开,或协议不是ssh或rdp: {}" + +#~ msgid "Empty" +#~ msgstr "空" + #~ msgid "Organization contains undeleted resources" #~ msgstr "组织包含未删除的资源" From e2406955bc8e59bfe803fdff8fb6cd56f717e91b Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 17 Mar 2021 17:08:49 +0800 Subject: [PATCH 13/13] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96license?= =?UTF-8?q?=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf: 优化license 过期 --- apps/jumpserver/settings/_xpack.py | 2 +- apps/jumpserver/settings/base.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/jumpserver/settings/_xpack.py b/apps/jumpserver/settings/_xpack.py index 8957d83c4..9f4319a35 100644 --- a/apps/jumpserver/settings/_xpack.py +++ b/apps/jumpserver/settings/_xpack.py @@ -12,7 +12,7 @@ XPACK_CONTEXT_PROCESSOR = [] if XPACK_ENABLED: from xpack.utils import get_xpack_templates_dir, get_xpack_context_processor - INSTALLED_APPS.append('xpack.apps.XpackConfig') + INSTALLED_APPS.insert(0, 'xpack.apps.XpackConfig') XPACK_TEMPLATES_DIR = get_xpack_templates_dir(const.BASE_DIR) XPACK_CONTEXT_PROCESSOR = get_xpack_context_processor() TEMPLATES[0]['DIRS'].extend(XPACK_TEMPLATES_DIR) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index 3e5a4ff6a..d4a8ce27a 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -42,13 +42,13 @@ INSTALLED_APPS = [ 'perms.apps.PermsConfig', 'ops.apps.OpsConfig', 'settings.apps.SettingsConfig', - 'common.apps.CommonConfig', 'terminal.apps.TerminalConfig', 'audits.apps.AuditsConfig', 'authentication.apps.AuthenticationConfig', # authentication 'applications.apps.ApplicationsConfig', 'tickets.apps.TicketsConfig', 'acls.apps.AclsConfig', + 'common.apps.CommonConfig', 'jms_oidc_rp', 'rest_framework', 'rest_framework_swagger',