From 3b1d19966919d2c4063b6fc1a63bfe709736d91c Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Wed, 22 Sep 2021 11:16:06 +0800 Subject: [PATCH 01/11] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DKoKo=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=97=B6=EF=BC=8C=E6=9C=AA=E5=BC=80=E5=90=AFSMS?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=87=BA=E7=8E=B0=E4=BA=86SMS=E9=80=89?= =?UTF-8?q?=E9=A1=B9=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/models/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 385e085da..cca83f2a6 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -537,7 +537,7 @@ class MFAMixin: methods = [] if self.otp_secret_key: methods.append(MFAType.OTP) - if self.phone: + if settings.XPACK_ENABLED and settings.SMS_ENABLED and self.phone: methods.append(MFAType.SMS_CODE) return methods From 26fc56b4be1b5f1357f52c5f9c3bb7abd87a6912 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 17 Sep 2021 16:00:23 +0800 Subject: [PATCH 02/11] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95html?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/authentication/login.html | 38 ++++------------- apps/authentication/views/login.py | 40 ++++++++++++++++++ apps/static/img/login_feishu_logo.png | Bin 6640 -> 2916 bytes apps/static/img/login_oidc_logo.png | Bin 0 -> 1885 bytes 4 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 apps/static/img/login_oidc_logo.png diff --git a/apps/authentication/templates/authentication/login.html b/apps/authentication/templates/authentication/login.html index dfc0f3d9b..08591892b 100644 --- a/apps/authentication/templates/authentication/login.html +++ b/apps/authentication/templates/authentication/login.html @@ -146,11 +146,9 @@
{% csrf_token %}
- {% if form.errors %} + {% if form.non_field_errors %}

- {% if form.non_field_errors %} - {{ form.non_field_errors.as_text }} - {% endif %} + {{ form.non_field_errors.as_text }}

{% else %}

@@ -197,35 +195,15 @@

- {% if AUTH_OPENID or AUTH_CAS or AUTH_WECOM or AUTH_DINGTALK or AUTH_FEISHU %} + {% if auth_methods %}
- {% trans "More login options" %} - {% if AUTH_OPENID %} - - {% endif %} - {% if AUTH_CAS %} - - {% endif %} - {% if AUTH_WECOM %} - - {% endif %} - {% if AUTH_DINGTALK %} - - {% endif %} - {% if AUTH_FEISHU %} - - {% endif %} + {% endfor %}
{% else %}
diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py index a33d8cee8..a916db1bc 100644 --- a/apps/authentication/views/login.py +++ b/apps/authentication/views/login.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import os import datetime +from django.templatetags.static import static from django.contrib.auth import login as auth_login, logout as auth_logout from django.http import HttpResponse from django.shortcuts import reverse, redirect @@ -136,6 +137,43 @@ class UserLoginView(mixins.AuthMixin, FormView): self.request.session[RSA_PRIVATE_KEY] = None self.request.session[RSA_PUBLIC_KEY] = None + @staticmethod + def get_support_auth_methods(): + auth_methods = [ + { + 'name': 'OpenID', + 'enabled': settings.AUTH_OPENID, + 'url': reverse('authentication:openid:login'), + 'logo': static('img/login_oidc_logo.png') + }, + { + 'name': 'CAS', + 'enabled': settings.AUTH_CAS, + 'url': reverse('authentication:cas:cas-login'), + 'logo': static('img/login_cas_logo.png') + }, + { + 'name': _('WeCom'), + 'enabled': settings.AUTH_WECOM, + 'url': reverse('authentication:wecom-qr-login'), + 'logo': static('img/login_wecom_logo.png') + }, + { + 'name': _('DingTalk'), + 'enabled': settings.AUTH_DINGTALK, + 'url': reverse('authentication:dingtalk-qr-login'), + 'logo': static('img/login_dingtalk_logo.png') + }, + { + 'name': _('FeiShu'), + 'enabled': settings.AUTH_FEISHU, + 'url': reverse('authentication:feishu-qr-login'), + 'logo': static('img/login_feishu_logo.png') + } + ] + return [method for method in auth_methods] + # return [method for method in auth_methods if method['enabled']] + def get_context_data(self, **kwargs): forgot_password_url = reverse('authentication:forgot-password') has_other_auth_backend = settings.AUTHENTICATION_BACKENDS[0] != settings.AUTH_BACKEND_MODEL @@ -144,6 +182,8 @@ class UserLoginView(mixins.AuthMixin, FormView): context = { 'demo_mode': os.environ.get("DEMO_MODE"), + 'auth_methods': self.get_support_auth_methods(), + 'has_other_auth' 'AUTH_OPENID': settings.AUTH_OPENID, 'AUTH_CAS': settings.AUTH_CAS, 'AUTH_WECOM': settings.AUTH_WECOM, diff --git a/apps/static/img/login_feishu_logo.png b/apps/static/img/login_feishu_logo.png index 054f350f5c7047ac20c667e08298dfc1441e999a..1b9b51cf4e34b13dc333ea7670e0e796e1ac07bb 100644 GIT binary patch literal 2916 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 diff --git a/apps/static/img/login_oidc_logo.png b/apps/static/img/login_oidc_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0f2d5b5c3af30fbf4ead8b2573b8190860b3a9ba GIT binary patch literal 1885 zcmV-j2cr0iP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Rg2@wZ0DC9Ulk^le(JV``BRA}Dq+HH(nRUOCi z&&+Pi?$U=9w=J-;EkY}87Xb}M%|bAeRGu1Rgpl|E>I+5GD89hN2=O8D5k(2cU`#a_ z2_X@(s0hY~N-a$^K2S7jng!VsFx^t@wy@iMxW4$`X=kT1bMLmD*`2n(WM0h8IrrS} zIp?19|NqYA1XE$I9{^sttM9ODogaU;A#JtKGti}&!oEheIVZqXKu^Qfcn`jU-yRph zRX~^F8hik6MiJj^&Vs8#iv8f57DrSgGwjHx_&MZ7VF8&X?wPy*Nalf;3R6cJCwYgd=u5>HwZ9l7w@x z8f&m?`O8n{979Jp%mocl%=PK|yH&*9(Lf&X9xlhrEb?SNU2a23!Z zUV}Ga0B^*(B5v+T%lv+#*mY+NSp7aOBvVN-nK(n_$VE(JG=={=wqYy&fxVT_RSsTl zP;vuTsk|JQ2&ZBIeOOqd`qb>g=t3e!a$yR+H2tj;Gvp;ag~#vnIbr z$_>uNyVHjI>p(VA-J+8R@Cp15_u@BZ`e7Z|fSYh9epwT^3g}AVP`odNo{eU?RwT2j z(<27psucWtDfszmXIvxJmHVkNr7K`NaXmhj-ek5K$F8_D_~N zafNuz{*2e9^-Ee-6}SR+4L&EP?X_V9d1KM(E{$*jH|Mz7C~n2~%P%$omRP`U6)X3JVv9UmM0|O6 zkS@Hs1l%uzih4@$9Wk=a1TE>m>2FK=e~~z{S&i4Hop7F*q1_H&#XHec0=`c6JMjd* zErR)`!PZ&4_K7TN2OdcQUzGx{b!Zl>PCKRpr?-p!X+uW4lekAjKXazaPOj*HDY1Z# z;4k<|3b{Z7Y0Ima!akl+t_vR&(Mn5?a>)k0Uzz1uLstu{M=L{@vhqLR;f%5!xLuij z(u&X};BjH+Jd;s=rEmo=X;tWQ-{r3&-`t;3XDxmx5{|YKbgO_DE5fiJf-%G9&bw#Me`h@r=4laEo~NZxSik4Dk5~e{f2dL66}J!p7O1;~wV=f9nx^ zR@l0wLo|bfgP!Vnzj^S9)=c0E9T3U>4dUI-QkzJ)zl2AHmwbyj`#EFhqJf1SyN45! zIj61~A6HDpv+-%XS2%yOQR$d-s9^f(i(mNGW!>XL>yz4H`GhzNdbCkr#8(~RiiPZH zd{V5+Ka(AImus=`nXXI}Z{ELP#d=BIJY_zyY^UVOqlr} z5hi=XRQG(i1YI`8_hT@Hzes%Ky+Ithbsj>=vGOg?M1P;Z4$QYjMt=5@9(UEGr$S2xKBi5{o;&vW!fp->vrEa ze%9#bpHCOse9-HWY{_Y)PoqaPbqh^4XbkyHz zWq8G05UK# zF)c7TEipG#FgH3iGCDIdD=;uRFfguZz%&2=03~!qSaf7zbY(hiZ)9m^c>ppnGBGVM zIV~|aR4_L>H8MIgGAl4JIxsNbG Date: Sat, 18 Sep 2021 15:24:04 +0800 Subject: [PATCH 03/11] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/views/login.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py index a916db1bc..07fa7cc5a 100644 --- a/apps/authentication/views/login.py +++ b/apps/authentication/views/login.py @@ -122,7 +122,11 @@ class UserLoginView(mixins.AuthMixin, FormView): context = self.get_context_data(form=new_form) self.request.session.set_test_cookie() return self.render_to_response(context) - except (errors.PasswdTooSimple, errors.PasswordRequireResetError, errors.PasswdNeedUpdate) as e: + except ( + errors.PasswdTooSimple, + errors.PasswordRequireResetError, + errors.PasswdNeedUpdate + ) as e: return redirect(e.url) self.clear_rsa_key() return self.redirect_to_guard_view() @@ -174,22 +178,19 @@ class UserLoginView(mixins.AuthMixin, FormView): return [method for method in auth_methods] # return [method for method in auth_methods if method['enabled']] - def get_context_data(self, **kwargs): + @staticmethod + def get_forgot_password_url(): forgot_password_url = reverse('authentication:forgot-password') has_other_auth_backend = settings.AUTHENTICATION_BACKENDS[0] != settings.AUTH_BACKEND_MODEL if has_other_auth_backend and settings.FORGOT_PASSWORD_URL: forgot_password_url = settings.FORGOT_PASSWORD_URL + return forgot_password_url + def get_context_data(self, **kwargs): context = { 'demo_mode': os.environ.get("DEMO_MODE"), 'auth_methods': self.get_support_auth_methods(), - 'has_other_auth' - 'AUTH_OPENID': settings.AUTH_OPENID, - 'AUTH_CAS': settings.AUTH_CAS, - 'AUTH_WECOM': settings.AUTH_WECOM, - 'AUTH_DINGTALK': settings.AUTH_DINGTALK, - 'AUTH_FEISHU': settings.AUTH_FEISHU, - 'forgot_password_url': forgot_password_url + 'forgot_password_url': self.get_forgot_password_url() } kwargs.update(context) return super().get_context_data(**kwargs) From cafbd08986e419a4a18da1fc99efe1c1ec99be12 Mon Sep 17 00:00:00 2001 From: ibuler Date: Sat, 18 Sep 2021 15:46:41 +0800 Subject: [PATCH 04/11] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=95=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/views/login.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/authentication/views/login.py b/apps/authentication/views/login.py index 07fa7cc5a..16b76d1d7 100644 --- a/apps/authentication/views/login.py +++ b/apps/authentication/views/login.py @@ -175,8 +175,7 @@ class UserLoginView(mixins.AuthMixin, FormView): 'logo': static('img/login_feishu_logo.png') } ] - return [method for method in auth_methods] - # return [method for method in auth_methods if method['enabled']] + return [method for method in auth_methods if method['enabled']] @staticmethod def get_forgot_password_url(): From 592356244037f574626e480cf08db47c653a7818 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Wed, 22 Sep 2021 15:15:01 +0800 Subject: [PATCH 05/11] =?UTF-8?q?perf:=20=E5=B7=A5=E5=8D=95=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/tickets/permissions/comment.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/tickets/permissions/comment.py b/apps/tickets/permissions/comment.py index deea43d52..de21f367f 100644 --- a/apps/tickets/permissions/comment.py +++ b/apps/tickets/permissions/comment.py @@ -15,7 +15,4 @@ class IsApplicant(permissions.BasePermission): class IsAssignee(permissions.BasePermission): def has_permission(self, request, view): - if view.action == 'list': - return view.ticket.has_all_assignee(request.user) - elif view.action == 'create': - return view.ticket.has_current_assignee(request.user) + return view.ticket.has_all_assignee(request.user) From aec31128cf4b8847017b97a14e9cece177638d47 Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Thu, 23 Sep 2021 11:12:34 +0800 Subject: [PATCH 06/11] =?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/locale/zh/LC_MESSAGES/django.mo | Bin 95849 -> 96104 bytes apps/locale/zh/LC_MESSAGES/django.po | 160 +++++++++++++++------------ 2 files changed, 88 insertions(+), 72 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index f4fc0153399ff5f61a8f660980ec43739538b445..1e92c31f298797697323a5de6f2a6d9bdf3b8f2d 100644 GIT binary patch delta 27576 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 z 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 S<5|go6iIg^tP;?n)c*rr?;th+ delta 27369 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 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index a95e8dfba..f5128dcda 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-16 19:25+0800\n" +"POT-Creation-Date: 2021-09-23 11:11+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -281,7 +281,7 @@ msgstr "应用管理" #: applications/serializers/application.py:88 assets/models/label.py:21 #: perms/models/application_permission.py:20 #: perms/serializers/application/user_permission.py:33 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:22 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:24 #: xpack/plugins/change_auth_plan/models/app.py:25 msgid "Category" msgstr "类别" @@ -292,7 +292,7 @@ msgstr "类别" #: perms/serializers/application/user_permission.py:34 #: terminal/models/storage.py:55 terminal/models/storage.py:116 #: tickets/models/flow.py:51 tickets/models/ticket.py:48 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:29 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:31 #: xpack/plugins/change_auth_plan/models/app.py:28 #: xpack/plugins/change_auth_plan/models/app.py:148 msgid "Type" @@ -310,7 +310,7 @@ msgstr "" #: applications/serializers/application.py:59 #: applications/serializers/application.py:89 assets/serializers/label.py:13 #: perms/serializers/application/permission.py:16 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:26 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:28 msgid "Category display" msgstr "类别名称" @@ -318,7 +318,7 @@ msgstr "类别名称" #: applications/serializers/application.py:91 #: assets/serializers/system_user.py:26 audits/serializers.py:29 #: perms/serializers/application/permission.py:17 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:33 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:35 #: tickets/serializers/ticket/ticket.py:22 #: tickets/serializers/ticket/ticket.py:168 msgid "Type display" @@ -377,7 +377,7 @@ msgstr "目标URL" #: applications/serializers/attrs/application_type/vmware_client.py:30 #: assets/models/base.py:177 audits/signals_handler.py:65 #: authentication/forms.py:22 -#: authentication/templates/authentication/login.html:165 +#: authentication/templates/authentication/login.html:163 #: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21 #: users/templates/users/user_otp_check_password.html:13 #: users/templates/users/user_password_update.html:43 @@ -1091,7 +1091,7 @@ msgstr "成功" #: audits/models.py:43 ops/models/command.py:30 perms/models/base.py:49 #: terminal/models/session.py:52 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:55 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:57 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:47 #: xpack/plugins/change_auth_plan/models/base.py:105 #: xpack/plugins/change_auth_plan/models/base.py:189 @@ -1238,14 +1238,12 @@ msgstr "" msgid "Auth Token" msgstr "认证令牌" -#: audits/signals_handler.py:68 -#: authentication/templates/authentication/login.html:216 +#: audits/signals_handler.py:68 authentication/views/login.py:160 #: notifications/backends/__init__.py:11 users/models/user.py:660 msgid "WeCom" msgstr "企业微信" -#: audits/signals_handler.py:69 -#: authentication/templates/authentication/login.html:221 +#: audits/signals_handler.py:69 authentication/views/login.py:166 #: notifications/backends/__init__.py:12 users/models/user.py:661 msgid "DingTalk" msgstr "钉钉" @@ -1760,38 +1758,25 @@ msgstr "确认" msgid "Code error" msgstr "代码错误" -#: authentication/templates/authentication/login.html:157 +#: authentication/templates/authentication/login.html:155 msgid "Welcome back, please enter username and password to login" msgstr "欢迎回来,请输入用户名和密码登录" -#: authentication/templates/authentication/login.html:189 +#: authentication/templates/authentication/login.html:187 #: users/templates/users/forgot_password.html:15 #: users/templates/users/forgot_password.html:16 msgid "Forgot password" msgstr "忘记密码" -#: authentication/templates/authentication/login.html:196 +#: authentication/templates/authentication/login.html:194 #: templates/_header_bar.html:83 msgid "Login" msgstr "登录" -#: authentication/templates/authentication/login.html:203 +#: authentication/templates/authentication/login.html:201 msgid "More login options" msgstr "更多登录方式" -#: authentication/templates/authentication/login.html:206 -msgid "OpenID" -msgstr "OpenID" - -#: authentication/templates/authentication/login.html:211 -msgid "CAS" -msgstr "CAS" - -#: authentication/templates/authentication/login.html:226 -#: notifications/backends/__init__.py:14 users/models/user.py:662 -msgid "FeiShu" -msgstr "飞书" - #: authentication/templates/authentication/login_otp.html:24 msgid "Please enter the verification code" msgstr "请输入验证码" @@ -1930,19 +1915,24 @@ msgstr "请使用密码登录,然后绑定飞书" msgid "Binding FeiShu failed" msgstr "绑定飞书失败" -#: authentication/views/login.py:80 +#: authentication/views/login.py:81 msgid "Redirecting" msgstr "跳转中" -#: authentication/views/login.py:81 +#: authentication/views/login.py:82 msgid "Redirecting to {} authentication" msgstr "正在跳转到 {} 认证" -#: authentication/views/login.py:107 +#: authentication/views/login.py:108 msgid "Please enable cookies and try again." msgstr "设置你的浏览器支持cookie" -#: authentication/views/login.py:219 +#: authentication/views/login.py:172 notifications/backends/__init__.py:14 +#: users/models/user.py:662 +msgid "FeiShu" +msgstr "飞书" + +#: authentication/views/login.py:259 msgid "" "Wait for {} confirm, You also can copy link to her/him
\n" " Don't close this page" @@ -1950,15 +1940,15 @@ msgstr "" "等待 {} 确认, 你也可以复制链接发给他/她
\n" " 不要关闭本页面" -#: authentication/views/login.py:224 +#: authentication/views/login.py:264 msgid "No ticket found" msgstr "没有发现工单" -#: authentication/views/login.py:256 +#: authentication/views/login.py:296 msgid "Logout success" msgstr "退出登录成功" -#: authentication/views/login.py:257 +#: authentication/views/login.py:297 msgid "Logout success, return login page" msgstr "退出登录成功,返回到登录页面" @@ -2478,7 +2468,7 @@ msgid "User group" msgstr "用户组" #: perms/models/base.py:50 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:60 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:50 #: users/models/user.py:643 msgid "Date expired" @@ -4543,34 +4533,34 @@ msgstr "你有一个新的工单, 申请人 - {}" msgid "Your ticket has been processed, processor - {}" msgstr "你的工单已被处理, 处理人 - {}" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:18 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:20 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:18 msgid "Apply name" msgstr "应用名称" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:37 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:39 msgid "Apply applications" msgstr "申请应用" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:42 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:44 msgid "Apply applications display" msgstr "应用名称名称" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:46 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:48 msgid "Apply system users" msgstr "系统用户" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:51 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:53 msgid "Apply system user display" msgstr "批准的系统用户名称" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:71 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:73 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:63 #: tickets/serializers/ticket/ticket.py:127 msgid "Permission named `{}` already exists" msgstr "授权名称 `{}` 已存在" -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:80 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:89 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:72 msgid "The expiration date should be greater than the start date" msgstr "过期时间要大于开始时间" @@ -5686,7 +5676,7 @@ msgstr "* 新密码不能是最近 {} 次的密码" msgid "Reset password success, return to login page" msgstr "重置密码成功,返回到登录页面" -#: xpack/plugins/change_auth_plan/api/app.py:112 +#: xpack/plugins/change_auth_plan/api/app.py:113 #: xpack/plugins/change_auth_plan/api/asset.py:100 msgid "The parameter 'action' must be [{}]" msgstr "参数 'action' 必须是 [{}]" @@ -6071,48 +6061,68 @@ msgid "AF-Johannesburg" msgstr "非洲-约翰内斯堡" #: xpack/plugins/cloud/providers/huaweicloud.py:36 -msgid "AP-Bangkok" -msgstr "亚太-曼谷" +msgid "CN North-Beijing4" +msgstr "华北-北京4" #: xpack/plugins/cloud/providers/huaweicloud.py:37 -msgid "AP-Hong Kong" -msgstr "亚太-香港" +msgid "CN North-Beijing1" +msgstr "华北-北京1" #: xpack/plugins/cloud/providers/huaweicloud.py:38 -msgid "AP-Singapore" -msgstr "亚太-新加坡" +msgid "CN East-Shanghai2" +msgstr "华东-上海2" #: xpack/plugins/cloud/providers/huaweicloud.py:39 msgid "CN East-Shanghai1" msgstr "华东-上海1" #: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN East-Shanghai2" -msgstr "华东-上海2" - -#: xpack/plugins/cloud/providers/huaweicloud.py:41 -msgid "CN North-Beijing1" -msgstr "华北-北京1" - -#: xpack/plugins/cloud/providers/huaweicloud.py:42 -msgid "CN North-Beijing4" -msgstr "华北-北京4" - -#: xpack/plugins/cloud/providers/huaweicloud.py:43 -msgid "CN Northeast-Dalian" -msgstr "华北-大连" - -#: xpack/plugins/cloud/providers/huaweicloud.py:44 msgid "CN South-Guangzhou" msgstr "华南-广州" +#: xpack/plugins/cloud/providers/huaweicloud.py:41 +msgid "LA-Mexico City1" +msgstr "拉美-墨西哥城一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:42 +msgid "LA-Santiago" +msgstr "拉美-圣地亚哥" + +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "LA-Sao Paulo1" +msgstr "拉美-圣保罗一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 +msgid "EU-Paris" +msgstr "欧洲-巴黎" + #: xpack/plugins/cloud/providers/huaweicloud.py:45 msgid "CN Southwest-Guiyang1" msgstr "西南-贵阳1" #: xpack/plugins/cloud/providers/huaweicloud.py:46 -msgid "EU-Paris" -msgstr "欧洲-巴黎" +msgid "AP-Bangkok" +msgstr "亚太-曼谷" + +#: xpack/plugins/cloud/providers/huaweicloud.py:47 +msgid "AP-Singapore" +msgstr "亚太-新加坡" + +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN-Hong Kong" +msgstr "中国-香港" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "CN Northeast-Dalian" +msgstr "华北-大连" + +#: xpack/plugins/cloud/providers/huaweicloud.py:51 +msgid "CN North-Ulanqab1" +msgstr "华北-乌兰察布一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:52 +msgid "CN South-Guangzhou-InvitationOnly" +msgstr "华南-广州-友好用户环境" #: xpack/plugins/cloud/serializers/account_attrs.py:13 msgid "AccessKey ID" @@ -6134,16 +6144,16 @@ msgstr "租户 ID" msgid "Subscription ID" msgstr "订阅 ID" -#: xpack/plugins/cloud/serializers/account_attrs.py:81 -#: xpack/plugins/cloud/serializers/account_attrs.py:86 +#: xpack/plugins/cloud/serializers/account_attrs.py:87 +#: xpack/plugins/cloud/serializers/account_attrs.py:92 msgid "API Endpoint" msgstr "API 端点" -#: xpack/plugins/cloud/serializers/account_attrs.py:92 +#: xpack/plugins/cloud/serializers/account_attrs.py:98 msgid "Service account key" msgstr "账户密钥" -#: xpack/plugins/cloud/serializers/account_attrs.py:93 +#: xpack/plugins/cloud/serializers/account_attrs.py:99 msgid "The file is in JSON format" msgstr "JSON 格式的文件" @@ -6252,5 +6262,11 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" +#~ msgid "OpenID" +#~ msgstr "OpenID" + +#~ msgid "CAS" +#~ msgstr "CAS" + #~ msgid "Only " #~ msgstr "仅能从用户配置来源登录" From a9ddbcc0cdcb496bf86ab1c1b3c136fb8b6d9c00 Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Fri, 24 Sep 2021 11:45:39 +0800 Subject: [PATCH 07/11] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E7=94=A8=E6=88=B7=E5=92=8C=E8=B5=84=E4=BA=A7/?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E5=85=B3=E8=81=94=E6=97=B6=E8=B5=84=E4=BA=A7?= =?UTF-8?q?=E7=89=B9=E6=9D=83=E7=94=A8=E6=88=B7=E6=9B=B4=E6=96=B0=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/authbook.py | 16 +++++++++------- apps/assets/signals_handler/authbook.py | 6 ++++-- apps/assets/tasks/common.py | 11 ++++++++++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/apps/assets/models/authbook.py b/apps/assets/models/authbook.py index 180dc90f7..2707583da 100644 --- a/apps/assets/models/authbook.py +++ b/apps/assets/models/authbook.py @@ -94,25 +94,27 @@ class AuthBook(BaseUser, AbsConnectivity): i.private_key = self.private_key i.public_key = self.public_key i.comment = 'Update triggered by account {}'.format(self.id) - i.save(update_fields=['password', 'private_key', 'public_key']) + + # 不触发post_save信号 + self.__class__.objects.bulk_update(matched, fields=['password', 'private_key', 'public_key']) def remove_asset_admin_user_if_need(self): - if not self.asset or not self.asset.admin_user: + if not self.asset or not self.systemuser: return - if not self.systemuser.is_admin_user: + if not self.systemuser.is_admin_user or self.asset.admin_user != self.systemuser: return - logger.debug('Remove asset admin user: {} {}'.format(self.asset, self.systemuser)) self.asset.admin_user = None self.asset.save() + logger.debug('Remove asset admin user: {} {}'.format(self.asset, self.systemuser)) def update_asset_admin_user_if_need(self): - if not self.systemuser or not self.systemuser.is_admin_user: + if not self.asset or not self.systemuser: return - if not self.asset or self.asset.admin_user == self.systemuser: + if not self.systemuser.is_admin_user or self.asset.admin_user == self.systemuser: return - logger.debug('Update asset admin user: {} {}'.format(self.asset, self.systemuser)) self.asset.admin_user = self.systemuser self.asset.save() + logger.debug('Update asset admin user: {} {}'.format(self.asset, self.systemuser)) def __str__(self): return self.smart_name diff --git a/apps/assets/signals_handler/authbook.py b/apps/assets/signals_handler/authbook.py index 55abf5c55..f42d8627e 100644 --- a/apps/assets/signals_handler/authbook.py +++ b/apps/assets/signals_handler/authbook.py @@ -34,9 +34,11 @@ def on_authbook_post_delete(sender, instance, **kwargs): @receiver(post_save, sender=AuthBook) -def on_authbook_post_create(sender, instance, **kwargs): +def on_authbook_post_create(sender, instance, created, **kwargs): instance.sync_to_system_user_account() - instance.update_asset_admin_user_if_need() + if created: + # 只在创建时进行更新资产的管理用户 + instance.update_asset_admin_user_if_need() @receiver(pre_save, sender=AuthBook) diff --git a/apps/assets/tasks/common.py b/apps/assets/tasks/common.py index 5a92ec039..322a64fe1 100644 --- a/apps/assets/tasks/common.py +++ b/apps/assets/tasks/common.py @@ -4,6 +4,7 @@ from celery import shared_task from orgs.utils import tmp_to_root_org +from assets.models import AuthBook __all__ = ['add_nodes_assets_to_system_users'] @@ -15,4 +16,12 @@ def add_nodes_assets_to_system_users(nodes_keys, system_users): nodes = Node.objects.filter(key__in=nodes_keys) assets = Node.get_nodes_all_assets(*nodes) for system_user in system_users: - system_user.assets.add(*tuple(assets)) + """ 解决资产和节点进行关联时,已经关联过的节点不会触发 authbook post_save 信号, + 无法更新节点下所有资产的管理用户的问题 """ + for asset in assets: + defaults = {'asset': asset, 'system_user': system_user} + instance, created = AuthBook.objects.update_or_create( + defaults=defaults, asset=asset, systemuser=system_user + ) + # 只要关联都需要更新资产的管理用户 + instance.update_asset_admin_user_if_need() From 90d269d2a250d125be4ce94ef5ed22499d753cdd Mon Sep 17 00:00:00 2001 From: wojiushixiaobai <296015668@qq.com> Date: Fri, 24 Sep 2021 12:21:06 +0800 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d8652be34..2c8e20f30 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ COPY ./requirements/deb_requirements.txt ./requirements/deb_requirements.txt RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list \ && sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list \ && apt update \ - && apt -y install telnet iproute2 redis-tools default-mysql-client vim wget curl locales \ + && apt -y install telnet iproute2 redis-tools default-mysql-client vim wget curl locales procps \ && apt -y install $(cat requirements/deb_requirements.txt) \ && rm -rf /var/lib/apt/lists/* \ && localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 \ From 08cd91c42688fa6b5280eefb1794d1383cffb92d Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 24 Sep 2021 13:57:20 +0800 Subject: [PATCH 09/11] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E6=8E=88=E6=9D=83=E6=A0=91=EF=BC=8C=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E4=B8=8D=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/applications/api/mixin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/applications/api/mixin.py b/apps/applications/api/mixin.py index ff939bf0b..59bc51467 100644 --- a/apps/applications/api/mixin.py +++ b/apps/applications/api/mixin.py @@ -32,6 +32,8 @@ class SerializeApplicationToTreeNodeMixin: return node def serialize_applications_with_org(self, applications): + if not applications: + return [] root_node = self.create_root_node() tree_nodes = [root_node] organizations = self.filter_organizations(applications) From 2c74727b65e9bd5925b7490918524afb70a4af09 Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Fri, 24 Sep 2021 14:09:17 +0800 Subject: [PATCH 10/11] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=82=AE?= =?UTF-8?q?=E4=BB=B6=E6=B5=8B=E8=AF=95=E5=BA=8F=E5=88=97=E7=B1=BB=E5=8F=8A?= =?UTF-8?q?API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/api/email.py | 18 ++++++++++-------- apps/settings/serializers/email.py | 6 ------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/apps/settings/api/email.py b/apps/settings/api/email.py index 91163213a..0d758237b 100644 --- a/apps/settings/api/email.py +++ b/apps/settings/api/email.py @@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _ from common.permissions import IsSuperUser from common.utils import get_logger from .. import serializers +from django.conf import settings logger = get_logger(__file__) @@ -24,14 +25,15 @@ class MailTestingAPI(APIView): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) - email_host = serializer.validated_data['EMAIL_HOST'] - email_port = serializer.validated_data['EMAIL_PORT'] - email_host_user = serializer.validated_data["EMAIL_HOST_USER"] - email_host_password = serializer.validated_data['EMAIL_HOST_PASSWORD'] - email_from = serializer.validated_data["EMAIL_FROM"] - email_recipient = serializer.validated_data["EMAIL_RECIPIENT"] - email_use_ssl = serializer.validated_data['EMAIL_USE_SSL'] - email_use_tls = serializer.validated_data['EMAIL_USE_TLS'] + # 测试邮件时,邮件服务器信息从配置中获取 + email_host = settings.EMAIL_HOST + email_port = settings.EMAIL_PORT + email_host_user = settings.EMAIL_HOST_USER + email_host_password = settings.EMAIL_HOST_PASSWORD + email_from = serializer.validated_data.get('EMAIL_FROM') + email_use_ssl = settings.EMAIL_USE_SSL + email_use_tls = settings.EMAIL_USE_TLS + email_recipient = serializer.validated_data.get('EMAIL_RECIPIENT') # 设置 settings 的值,会导致动态配置在当前进程失效 # for k, v in serializer.validated_data.items(): diff --git a/apps/settings/serializers/email.py b/apps/settings/serializers/email.py index a20ff080c..3474de52a 100644 --- a/apps/settings/serializers/email.py +++ b/apps/settings/serializers/email.py @@ -8,14 +8,8 @@ __all__ = ['MailTestSerializer', 'EmailSettingSerializer', 'EmailContentSettingS class MailTestSerializer(serializers.Serializer): - EMAIL_HOST = serializers.CharField(max_length=1024, required=True) - EMAIL_PORT = serializers.IntegerField(default=25, min_value=1, max_value=65535) - EMAIL_HOST_USER = serializers.CharField(max_length=1024) - EMAIL_HOST_PASSWORD = serializers.CharField(required=False, allow_blank=True) EMAIL_FROM = serializers.CharField(required=False, allow_blank=True) EMAIL_RECIPIENT = serializers.CharField(required=False, allow_blank=True) - EMAIL_USE_SSL = serializers.BooleanField(default=False) - EMAIL_USE_TLS = serializers.BooleanField(default=False) class EmailSettingSerializer(serializers.Serializer): From e1eef0a3f3347f8ad02ce6de48449be3aba5d3fb Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Fri, 24 Sep 2021 20:14:23 +0800 Subject: [PATCH 11/11] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dauthbook=20syste?= =?UTF-8?q?muser=E5=AD=97=E6=AE=B5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/tasks/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/tasks/common.py b/apps/assets/tasks/common.py index 322a64fe1..ad2749e29 100644 --- a/apps/assets/tasks/common.py +++ b/apps/assets/tasks/common.py @@ -19,7 +19,7 @@ def add_nodes_assets_to_system_users(nodes_keys, system_users): """ 解决资产和节点进行关联时,已经关联过的节点不会触发 authbook post_save 信号, 无法更新节点下所有资产的管理用户的问题 """ for asset in assets: - defaults = {'asset': asset, 'system_user': system_user} + defaults = {'asset': asset, 'systemuser': system_user, 'org_id': asset.org_id} instance, created = AuthBook.objects.update_or_create( defaults=defaults, asset=asset, systemuser=system_user )