From fa68389028e091ac8da44ef835dbb4cc408f5d29 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 18 Oct 2021 11:25:39 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E5=8E=BB=E6=8E=89=E5=8D=95=E7=8B=AC?= =?UTF-8?q?=E7=9A=84flash=20msg=20(#7013)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 去掉单独的flash msg perf: 修改使用库 * fix: guangbug * pref: 修改 context Co-authored-by: ibuler Co-authored-by: xinwen --- apps/authentication/mixins.py | 4 +- apps/authentication/urls/view_urls.py | 6 - apps/authentication/views/dingtalk.py | 102 ++++++----------- apps/authentication/views/feishu.py | 104 ++++++----------- apps/authentication/views/wecom.py | 107 ++++++------------ .../message/backends/dingtalk/__init__.py | 23 ++-- .../message/backends/feishu/__init__.py | 4 +- apps/common/message/backends/utils.py | 10 +- .../common/message/backends/wecom/__init__.py | 12 +- apps/common/utils/common.py | 2 +- apps/common/utils/jumpserver.py | 17 +++ apps/common/views.py | 12 +- apps/settings/api/dingtalk.py | 23 ++-- apps/templates/flash_message_standalone.html | 39 ++++--- 14 files changed, 177 insertions(+), 288 deletions(-) diff --git a/apps/authentication/mixins.py b/apps/authentication/mixins.py index 5295d4c40..07beee3e7 100644 --- a/apps/authentication/mixins.py +++ b/apps/authentication/mixins.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # import inspect -from urllib.parse import urlencode +from django.utils.http import urlencode from functools import partial import time @@ -204,7 +204,7 @@ class AuthMixin(PasswordEncryptionViewMixin): data = request.POST items = ['username', 'password', 'challenge', 'public_key', 'auto_login'] - username, password, challenge, public_key, auto_login = bulk_get(data, *items, default='') + username, password, challenge, public_key, auto_login = bulk_get(data, items, default='') ip = self.get_request_ip() self._set_partial_credential_error(username=username, ip=ip, request=request) diff --git a/apps/authentication/urls/view_urls.py b/apps/authentication/urls/view_urls.py index 92d5818cb..1db4a477a 100644 --- a/apps/authentication/urls/view_urls.py +++ b/apps/authentication/urls/view_urls.py @@ -22,24 +22,18 @@ urlpatterns = [ path('password/reset/', users_view.UserResetPasswordView.as_view(), name='reset-password'), path('password/verify/', users_view.UserVerifyPasswordView.as_view(), name='user-verify-password'), - path('wecom/bind/success-flash-msg/', views.FlashWeComBindSucceedMsgView.as_view(), name='wecom-bind-success-flash-msg'), - path('wecom/bind/failed-flash-msg/', views.FlashWeComBindFailedMsgView.as_view(), name='wecom-bind-failed-flash-msg'), path('wecom/bind/start/', views.WeComEnableStartView.as_view(), name='wecom-bind-start'), path('wecom/qr/bind/', views.WeComQRBindView.as_view(), name='wecom-qr-bind'), path('wecom/qr/login/', views.WeComQRLoginView.as_view(), name='wecom-qr-login'), path('wecom/qr/bind//callback/', views.WeComQRBindCallbackView.as_view(), name='wecom-qr-bind-callback'), path('wecom/qr/login/callback/', views.WeComQRLoginCallbackView.as_view(), name='wecom-qr-login-callback'), - path('dingtalk/bind/success-flash-msg/', views.FlashDingTalkBindSucceedMsgView.as_view(), name='dingtalk-bind-success-flash-msg'), - path('dingtalk/bind/failed-flash-msg/', views.FlashDingTalkBindFailedMsgView.as_view(), name='dingtalk-bind-failed-flash-msg'), path('dingtalk/bind/start/', views.DingTalkEnableStartView.as_view(), name='dingtalk-bind-start'), path('dingtalk/qr/bind/', views.DingTalkQRBindView.as_view(), name='dingtalk-qr-bind'), path('dingtalk/qr/login/', views.DingTalkQRLoginView.as_view(), name='dingtalk-qr-login'), path('dingtalk/qr/bind//callback/', views.DingTalkQRBindCallbackView.as_view(), name='dingtalk-qr-bind-callback'), path('dingtalk/qr/login/callback/', views.DingTalkQRLoginCallbackView.as_view(), name='dingtalk-qr-login-callback'), - path('feishu/bind/success-flash-msg/', views.FlashDingTalkBindSucceedMsgView.as_view(), name='feishu-bind-success-flash-msg'), - path('feishu/bind/failed-flash-msg/', views.FlashDingTalkBindFailedMsgView.as_view(), name='feishu-bind-failed-flash-msg'), path('feishu/bind/start/', views.FeiShuEnableStartView.as_view(), name='feishu-bind-start'), path('feishu/qr/bind/', views.FeiShuQRBindView.as_view(), name='feishu-qr-bind'), path('feishu/qr/login/', views.FeiShuQRLoginView.as_view(), name='feishu-qr-login'), diff --git a/apps/authentication/views/dingtalk.py b/apps/authentication/views/dingtalk.py index 6ec625e0d..34a25454b 100644 --- a/apps/authentication/views/dingtalk.py +++ b/apps/authentication/views/dingtalk.py @@ -1,10 +1,6 @@ -import urllib - from django.http.response import HttpResponseRedirect -from django.utils.decorators import method_decorator from django.utils.translation import ugettext_lazy as _ -from django.views.decorators.cache import never_cache -from django.views.generic import TemplateView +from urllib.parse import urlencode from django.views import View from django.conf import settings from django.http.request import HttpRequest @@ -15,7 +11,7 @@ from rest_framework.exceptions import APIException from users.views import UserVerifyPasswordView from users.utils import is_auth_password_time_valid from users.models import User -from common.utils import get_logger +from common.utils import get_logger, FlashMessageUtil from common.utils.random import random_string from common.utils.django import reverse, get_object_or_none from common.message.backends.dingtalk import URL @@ -39,7 +35,7 @@ class DingTalkQRMixin(PermissionsMixin, View): msg = e.detail['errmsg'] except Exception: msg = _('DingTalk Error, Please contact your system administrator') - return self.get_failed_reponse( + return self.get_failed_response( '/', _('DingTalk Error'), msg @@ -67,30 +63,32 @@ class DingTalkQRMixin(PermissionsMixin, View): 'state': state, 'redirect_uri': redirect_uri, } - url = URL.QR_CONNECT + '?' + urllib.parse.urlencode(params) + url = URL.QR_CONNECT + '?' + urlencode(params) return url - def get_success_reponse(self, redirect_url, title, msg): - ok_flash_msg_url = reverse('authentication:dingtalk-bind-success-flash-msg') - ok_flash_msg_url += '?' + urllib.parse.urlencode({ - 'redirect_url': redirect_url, + @staticmethod + def get_success_response(redirect_url, title, msg): + message_data = { 'title': title, - 'msg': msg - }) - return HttpResponseRedirect(ok_flash_msg_url) + 'message': msg, + 'interval': 5, + 'redirect_url': redirect_url, + } + return FlashMessageUtil.gen_and_redirect_to(message_data) - def get_failed_reponse(self, redirect_url, title, msg): - failed_flash_msg_url = reverse('authentication:dingtalk-bind-failed-flash-msg') - failed_flash_msg_url += '?' + urllib.parse.urlencode({ - 'redirect_url': redirect_url, + @staticmethod + def get_failed_response(redirect_url, title, msg): + message_data = { 'title': title, - 'msg': msg - }) - return HttpResponseRedirect(failed_flash_msg_url) + 'error': msg, + 'interval': 5, + 'redirect_url': redirect_url, + } + return FlashMessageUtil.gen_and_redirect_to(message_data) def get_already_bound_response(self, redirect_url): msg = _('DingTalk is already bound') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response @@ -103,11 +101,11 @@ class DingTalkQRBindView(DingTalkQRMixin, View): if not is_auth_password_time_valid(request.session): msg = _('Please verify your password first') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response redirect_uri = reverse('authentication:dingtalk-qr-bind-callback', kwargs={'user_id': user.id}, external=True) - redirect_uri += '?' + urllib.parse.urlencode({'redirect_url': redirect_url}) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) url = self.get_qr_url(redirect_uri) return HttpResponseRedirect(url) @@ -127,7 +125,7 @@ class DingTalkQRBindCallbackView(DingTalkQRMixin, View): if user is None: logger.error(f'DingTalkQR bind callback error, user_id invalid: user_id={user_id}') msg = _('Invalid user_id') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response if user.dingtalk_id: @@ -143,7 +141,7 @@ class DingTalkQRBindCallbackView(DingTalkQRMixin, View): if not userid: msg = _('DingTalk query user failed') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response try: @@ -152,12 +150,12 @@ class DingTalkQRBindCallbackView(DingTalkQRMixin, View): except IntegrityError as e: if e.args[0] == 1062: msg = _('The DingTalk is already bound to another user') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response raise e msg = _('Binding DingTalk successfully') - response = self.get_success_reponse(redirect_url, msg, msg) + response = self.get_success_response(redirect_url, msg, msg) return response @@ -169,7 +167,7 @@ class DingTalkEnableStartView(UserVerifyPasswordView): success_url = reverse('authentication:dingtalk-qr-bind') - success_url += '?' + urllib.parse.urlencode({ + success_url += '?' + urlencode({ 'redirect_url': redirect_url or referer }) @@ -183,7 +181,7 @@ class DingTalkQRLoginView(DingTalkQRMixin, View): redirect_url = request.GET.get('redirect_url') redirect_uri = reverse('authentication:dingtalk-qr-login-callback', external=True) - redirect_uri += '?' + urllib.parse.urlencode({'redirect_url': redirect_url}) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) url = self.get_qr_url(redirect_uri) return HttpResponseRedirect(url) @@ -209,14 +207,14 @@ class DingTalkQRLoginCallbackView(AuthMixin, DingTalkQRMixin, View): if not userid: # 正常流程不会出这个错误,hack 行为 msg = _('Failed to get user from DingTalk') - response = self.get_failed_reponse(login_url, title=msg, msg=msg) + response = self.get_failed_response(login_url, title=msg, msg=msg) return response user = get_object_or_none(User, dingtalk_id=userid) if user is None: title = _('DingTalk is not bound') msg = _('Please login with a password and then bind the DingTalk') - response = self.get_failed_reponse(login_url, title=title, msg=msg) + response = self.get_failed_response(login_url, title=title, msg=msg) return response try: @@ -224,43 +222,7 @@ class DingTalkQRLoginCallbackView(AuthMixin, DingTalkQRMixin, View): except errors.AuthFailedError as e: self.set_login_failed_mark() msg = e.msg - response = self.get_failed_reponse(login_url, title=msg, msg=msg) + response = self.get_failed_response(login_url, title=msg, msg=msg) return response return self.redirect_to_guard_view() - - -@method_decorator(never_cache, name='dispatch') -class FlashDingTalkBindSucceedMsgView(TemplateView): - template_name = 'flash_message_standalone.html' - - def get(self, request, *args, **kwargs): - title = request.GET.get('title') - msg = request.GET.get('msg') - - context = { - 'title': title or _('Binding DingTalk successfully'), - 'messages': msg or _('Binding DingTalk successfully'), - 'interval': 5, - 'redirect_url': request.GET.get('redirect_url'), - 'auto_redirect': True, - } - return self.render_to_response(context) - - -@method_decorator(never_cache, name='dispatch') -class FlashDingTalkBindFailedMsgView(TemplateView): - template_name = 'flash_message_standalone.html' - - def get(self, request, *args, **kwargs): - title = request.GET.get('title') - msg = request.GET.get('msg') - - context = { - 'title': title or _('Binding DingTalk failed'), - 'messages': msg or _('Binding DingTalk failed'), - 'interval': 5, - 'redirect_url': request.GET.get('redirect_url'), - 'auto_redirect': True, - } - return self.render_to_response(context) diff --git a/apps/authentication/views/feishu.py b/apps/authentication/views/feishu.py index ac18cde40..19f9f0bb3 100644 --- a/apps/authentication/views/feishu.py +++ b/apps/authentication/views/feishu.py @@ -1,10 +1,6 @@ -import urllib - -from django.http.response import HttpResponseRedirect, HttpResponse -from django.utils.decorators import method_decorator +from django.http.response import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ -from django.views.decorators.cache import never_cache -from django.views.generic import TemplateView +from urllib.parse import urlencode from django.views import View from django.conf import settings from django.http.request import HttpRequest @@ -15,7 +11,7 @@ from rest_framework.exceptions import APIException from users.utils import is_auth_password_time_valid from users.views import UserVerifyPasswordView from users.models import User -from common.utils import get_logger +from common.utils import get_logger, FlashMessageUtil from common.utils.random import random_string from common.utils.django import reverse, get_object_or_none from common.mixins.views import PermissionsMixin @@ -35,7 +31,7 @@ class FeiShuQRMixin(PermissionsMixin, View): return super().dispatch(request, *args, **kwargs) except APIException as e: msg = str(e.detail) - return self.get_failed_reponse( + return self.get_failed_response( '/', _('FeiShu Error'), msg @@ -50,7 +46,7 @@ class FeiShuQRMixin(PermissionsMixin, View): def get_verify_state_failed_response(self, redirect_uri): msg = _("The system configuration is incorrect. Please contact your administrator") - return self.get_failed_reponse(redirect_uri, msg, msg) + return self.get_failed_response(redirect_uri, msg, msg) def get_qr_url(self, redirect_uri): state = random_string(16) @@ -61,30 +57,32 @@ class FeiShuQRMixin(PermissionsMixin, View): 'state': state, 'redirect_uri': redirect_uri, } - url = URL.AUTHEN + '?' + urllib.parse.urlencode(params) + url = URL.AUTHEN + '?' + urlencode(params) return url - def get_success_reponse(self, redirect_url, title, msg): - ok_flash_msg_url = reverse('authentication:feishu-bind-success-flash-msg') - ok_flash_msg_url += '?' + urllib.parse.urlencode({ - 'redirect_url': redirect_url, + @staticmethod + def get_success_response(redirect_url, title, msg): + message_data = { 'title': title, - 'msg': msg - }) - return HttpResponseRedirect(ok_flash_msg_url) + 'message': msg, + 'interval': 5, + 'redirect_url': redirect_url, + } + return FlashMessageUtil.gen_and_redirect_to(message_data) - def get_failed_reponse(self, redirect_url, title, msg): - failed_flash_msg_url = reverse('authentication:feishu-bind-failed-flash-msg') - failed_flash_msg_url += '?' + urllib.parse.urlencode({ - 'redirect_url': redirect_url, + @staticmethod + def get_failed_response(redirect_url, title, msg): + message_data = { 'title': title, - 'msg': msg - }) - return HttpResponseRedirect(failed_flash_msg_url) + 'error': msg, + 'interval': 5, + 'redirect_url': redirect_url, + } + return FlashMessageUtil.gen_and_redirect_to(message_data) def get_already_bound_response(self, redirect_url): msg = _('FeiShu is already bound') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response @@ -97,11 +95,11 @@ class FeiShuQRBindView(FeiShuQRMixin, View): if not is_auth_password_time_valid(request.session): msg = _('Please verify your password first') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response redirect_uri = reverse('authentication:feishu-qr-bind-callback', external=True) - redirect_uri += '?' + urllib.parse.urlencode({'redirect_url': redirect_url}) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) url = self.get_qr_url(redirect_uri) return HttpResponseRedirect(url) @@ -131,7 +129,7 @@ class FeiShuQRBindCallbackView(FeiShuQRMixin, View): if not user_id: msg = _('FeiShu query user failed') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response try: @@ -140,12 +138,12 @@ class FeiShuQRBindCallbackView(FeiShuQRMixin, View): except IntegrityError as e: if e.args[0] == 1062: msg = _('The FeiShu is already bound to another user') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response raise e msg = _('Binding FeiShu successfully') - response = self.get_success_reponse(redirect_url, msg, msg) + response = self.get_success_response(redirect_url, msg, msg) return response @@ -157,7 +155,7 @@ class FeiShuEnableStartView(UserVerifyPasswordView): success_url = reverse('authentication:feishu-qr-bind') - success_url += '?' + urllib.parse.urlencode({ + success_url += '?' + urlencode({ 'redirect_url': redirect_url or referer }) @@ -171,7 +169,7 @@ class FeiShuQRLoginView(FeiShuQRMixin, View): redirect_url = request.GET.get('redirect_url') redirect_uri = reverse('authentication:feishu-qr-login-callback', external=True) - redirect_uri += '?' + urllib.parse.urlencode({'redirect_url': redirect_url}) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) url = self.get_qr_url(redirect_uri) return HttpResponseRedirect(url) @@ -196,14 +194,14 @@ class FeiShuQRLoginCallbackView(AuthMixin, FeiShuQRMixin, View): if not user_id: # 正常流程不会出这个错误,hack 行为 msg = _('Failed to get user from FeiShu') - response = self.get_failed_reponse(login_url, title=msg, msg=msg) + response = self.get_failed_response(login_url, title=msg, msg=msg) return response user = get_object_or_none(User, feishu_id=user_id) if user is None: title = _('FeiShu is not bound') msg = _('Please login with a password and then bind the FeiShu') - response = self.get_failed_reponse(login_url, title=title, msg=msg) + response = self.get_failed_response(login_url, title=title, msg=msg) return response try: @@ -211,43 +209,7 @@ class FeiShuQRLoginCallbackView(AuthMixin, FeiShuQRMixin, View): except errors.AuthFailedError as e: self.set_login_failed_mark() msg = e.msg - response = self.get_failed_reponse(login_url, title=msg, msg=msg) + response = self.get_failed_response(login_url, title=msg, msg=msg) return response return self.redirect_to_guard_view() - - -@method_decorator(never_cache, name='dispatch') -class FlashFeiShuBindSucceedMsgView(TemplateView): - template_name = 'flash_message_standalone.html' - - def get(self, request, *args, **kwargs): - title = request.GET.get('title') - msg = request.GET.get('msg') - - context = { - 'title': title or _('Binding FeiShu successfully'), - 'messages': msg or _('Binding FeiShu successfully'), - 'interval': 5, - 'redirect_url': request.GET.get('redirect_url'), - 'auto_redirect': True, - } - return self.render_to_response(context) - - -@method_decorator(never_cache, name='dispatch') -class FlashFeiShuBindFailedMsgView(TemplateView): - template_name = 'flash_message_standalone.html' - - def get(self, request, *args, **kwargs): - title = request.GET.get('title') - msg = request.GET.get('msg') - - context = { - 'title': title or _('Binding FeiShu failed'), - 'messages': msg or _('Binding FeiShu failed'), - 'interval': 5, - 'redirect_url': request.GET.get('redirect_url'), - 'auto_redirect': True, - } - return self.render_to_response(context) diff --git a/apps/authentication/views/wecom.py b/apps/authentication/views/wecom.py index a55fb2704..c3e9068e5 100644 --- a/apps/authentication/views/wecom.py +++ b/apps/authentication/views/wecom.py @@ -1,10 +1,6 @@ -import urllib - from django.http.response import HttpResponseRedirect -from django.utils.decorators import method_decorator from django.utils.translation import ugettext_lazy as _ -from django.views.decorators.cache import never_cache -from django.views.generic import TemplateView +from urllib.parse import urlencode from django.views import View from django.conf import settings from django.http.request import HttpRequest @@ -15,7 +11,7 @@ from rest_framework.exceptions import APIException from users.views import UserVerifyPasswordView from users.utils import is_auth_password_time_valid from users.models import User -from common.utils import get_logger +from common.utils import get_logger, FlashMessageUtil from common.utils.random import random_string from common.utils.django import reverse, get_object_or_none from common.message.backends.wecom import URL @@ -39,7 +35,7 @@ class WeComQRMixin(PermissionsMixin, View): msg = e.detail['errmsg'] except Exception: msg = _('WeCom Error, Please contact your system administrator') - return self.get_failed_reponse( + return self.get_failed_response( '/', _('WeCom Error'), msg @@ -54,7 +50,7 @@ class WeComQRMixin(PermissionsMixin, View): def get_verify_state_failed_response(self, redirect_uri): msg = _("The system configuration is incorrect. Please contact your administrator") - return self.get_failed_reponse(redirect_uri, msg, msg) + return self.get_failed_response(redirect_uri, msg, msg) def get_qr_url(self, redirect_uri): state = random_string(16) @@ -66,30 +62,32 @@ class WeComQRMixin(PermissionsMixin, View): 'state': state, 'redirect_uri': redirect_uri, } - url = URL.QR_CONNECT + '?' + urllib.parse.urlencode(params) + url = URL.QR_CONNECT + '?' + urlencode(params) return url - def get_success_reponse(self, redirect_url, title, msg): - ok_flash_msg_url = reverse('authentication:wecom-bind-success-flash-msg') - ok_flash_msg_url += '?' + urllib.parse.urlencode({ - 'redirect_url': redirect_url, + @staticmethod + def get_success_response(redirect_url, title, msg): + message_data = { 'title': title, - 'msg': msg - }) - return HttpResponseRedirect(ok_flash_msg_url) + 'message': msg, + 'interval': 5, + 'redirect_url': redirect_url, + } + return FlashMessageUtil.gen_and_redirect_to(message_data) - def get_failed_reponse(self, redirect_url, title, msg): - failed_flash_msg_url = reverse('authentication:wecom-bind-failed-flash-msg') - failed_flash_msg_url += '?' + urllib.parse.urlencode({ - 'redirect_url': redirect_url, + @staticmethod + def get_failed_response(redirect_url, title, msg): + message_data = { 'title': title, - 'msg': msg - }) - return HttpResponseRedirect(failed_flash_msg_url) + 'error': msg, + 'interval': 5, + 'redirect_url': redirect_url, + } + return FlashMessageUtil.gen_and_redirect_to(message_data) def get_already_bound_response(self, redirect_url): msg = _('WeCom is already bound') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response @@ -102,11 +100,11 @@ class WeComQRBindView(WeComQRMixin, View): if not is_auth_password_time_valid(request.session): msg = _('Please verify your password first') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response redirect_uri = reverse('authentication:wecom-qr-bind-callback', kwargs={'user_id': user.id}, external=True) - redirect_uri += '?' + urllib.parse.urlencode({'redirect_url': redirect_url}) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) url = self.get_qr_url(redirect_uri) return HttpResponseRedirect(url) @@ -126,7 +124,7 @@ class WeComQRBindCallbackView(WeComQRMixin, View): if user is None: logger.error(f'WeComQR bind callback error, user_id invalid: user_id={user_id}') msg = _('Invalid user_id') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response if user.wecom_id: @@ -141,7 +139,7 @@ class WeComQRBindCallbackView(WeComQRMixin, View): wecom_userid, __ = wecom.get_user_id_by_code(code) if not wecom_userid: msg = _('WeCom query user failed') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response try: @@ -150,27 +148,24 @@ class WeComQRBindCallbackView(WeComQRMixin, View): except IntegrityError as e: if e.args[0] == 1062: msg = _('The WeCom is already bound to another user') - response = self.get_failed_reponse(redirect_url, msg, msg) + response = self.get_failed_response(redirect_url, msg, msg) return response raise e msg = _('Binding WeCom successfully') - response = self.get_success_reponse(redirect_url, msg, msg) + response = self.get_success_response(redirect_url, msg, msg) return response class WeComEnableStartView(UserVerifyPasswordView): - def get_success_url(self): referer = self.request.META.get('HTTP_REFERER') redirect_url = self.request.GET.get("redirect_url") success_url = reverse('authentication:wecom-qr-bind') - - success_url += '?' + urllib.parse.urlencode({ + success_url += '?' + urlencode({ 'redirect_url': redirect_url or referer }) - return success_url @@ -181,7 +176,7 @@ class WeComQRLoginView(WeComQRMixin, View): redirect_url = request.GET.get('redirect_url') redirect_uri = reverse('authentication:wecom-qr-login-callback', external=True) - redirect_uri += '?' + urllib.parse.urlencode({'redirect_url': redirect_url}) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) url = self.get_qr_url(redirect_uri) return HttpResponseRedirect(url) @@ -207,14 +202,14 @@ class WeComQRLoginCallbackView(AuthMixin, WeComQRMixin, View): if not wecom_userid: # 正常流程不会出这个错误,hack 行为 msg = _('Failed to get user from WeCom') - response = self.get_failed_reponse(login_url, title=msg, msg=msg) + response = self.get_failed_response(login_url, title=msg, msg=msg) return response user = get_object_or_none(User, wecom_id=wecom_userid) if user is None: title = _('WeCom is not bound') msg = _('Please login with a password and then bind the WeCom') - response = self.get_failed_reponse(login_url, title=title, msg=msg) + response = self.get_failed_response(login_url, title=title, msg=msg) return response try: @@ -222,43 +217,7 @@ class WeComQRLoginCallbackView(AuthMixin, WeComQRMixin, View): except errors.AuthFailedError as e: self.set_login_failed_mark() msg = e.msg - response = self.get_failed_reponse(login_url, title=msg, msg=msg) + response = self.get_failed_response(login_url, title=msg, msg=msg) return response return self.redirect_to_guard_view() - - -@method_decorator(never_cache, name='dispatch') -class FlashWeComBindSucceedMsgView(TemplateView): - template_name = 'flash_message_standalone.html' - - def get(self, request, *args, **kwargs): - title = request.GET.get('title') - msg = request.GET.get('msg') - - context = { - 'title': title or _('Binding WeCom successfully'), - 'messages': msg or _('Binding WeCom successfully'), - 'interval': 5, - 'redirect_url': request.GET.get('redirect_url'), - 'auto_redirect': True, - } - return self.render_to_response(context) - - -@method_decorator(never_cache, name='dispatch') -class FlashWeComBindFailedMsgView(TemplateView): - template_name = 'flash_message_standalone.html' - - def get(self, request, *args, **kwargs): - title = request.GET.get('title') - msg = request.GET.get('msg') - - context = { - 'title': title or _('Binding WeCom failed'), - 'messages': msg or _('Binding WeCom failed'), - 'interval': 5, - 'redirect_url': request.GET.get('redirect_url'), - 'auto_redirect': True, - } - return self.render_to_response(context) diff --git a/apps/common/message/backends/dingtalk/__init__.py b/apps/common/message/backends/dingtalk/__init__.py index 1c8a5b59c..3f07ba2a0 100644 --- a/apps/common/message/backends/dingtalk/__init__.py +++ b/apps/common/message/backends/dingtalk/__init__.py @@ -14,7 +14,8 @@ def sign(secret, data): digest = hmac.HMAC( key=secret.encode('utf8'), msg=data.encode('utf8'), - digestmod=hmac._hashlib.sha256).digest() + digestmod=hmac._hashlib.sha256 + ).digest() signature = base64.standard_b64encode(digest).decode('utf8') # signature = urllib.parse.quote(signature, safe='') # signature = signature.replace('+', '%20').replace('*', '%2A').replace('~', '%7E').replace('/', '%2F') @@ -39,9 +40,9 @@ class DingTalkRequests(BaseRequest): invalid_token_errcodes = (ErrorCode.INVALID_TOKEN,) def __init__(self, appid, appsecret, agentid, timeout=None): - self._appid = appid - self._appsecret = appsecret - self._agentid = agentid + self._appid = appid or '' + self._appsecret = appsecret or '' + self._agentid = agentid or '' super().__init__(timeout=timeout) @@ -74,7 +75,7 @@ class DingTalkRequests(BaseRequest): def post(self, url, json=None, params=None, with_token=False, with_sign=False, check_errcode_is_0=True, - **kwargs): + **kwargs) -> dict: pass post = as_request(post) @@ -86,11 +87,10 @@ class DingTalkRequests(BaseRequest): timestamp = str(int(time.time() * 1000)) signature = sign(self._appsecret, timestamp) - accessKey = self._appid params['timestamp'] = timestamp params['signature'] = signature - params['accessKey'] = accessKey + params['accessKey'] = self._appid def request(self, method, url, with_token=False, with_sign=False, @@ -102,15 +102,16 @@ class DingTalkRequests(BaseRequest): data = super().request( method, url, with_token=with_token, - check_errcode_is_0=check_errcode_is_0, **kwargs) + check_errcode_is_0=check_errcode_is_0, **kwargs + ) return data class DingTalk: def __init__(self, appid, appsecret, agentid, timeout=None): - self._appid = appid - self._appsecret = appsecret - self._agentid = agentid + self._appid = appid or '' + self._appsecret = appsecret or '' + self._agentid = agentid or '' self._request = DingTalkRequests( appid=appid, appsecret=appsecret, agentid=agentid, diff --git a/apps/common/message/backends/feishu/__init__.py b/apps/common/message/backends/feishu/__init__.py index 3bc67b1b5..f9f1ee0e4 100644 --- a/apps/common/message/backends/feishu/__init__.py +++ b/apps/common/message/backends/feishu/__init__.py @@ -69,8 +69,8 @@ class FeiShu(RequestMixin): """ def __init__(self, app_id, app_secret, timeout=None): - self._app_id = app_id - self._app_secret = app_secret + self._app_id = app_id or '' + self._app_secret = app_secret or '' self._requests = FeishuRequests( app_id=app_id, diff --git a/apps/common/message/backends/utils.py b/apps/common/message/backends/utils.py index 1a1a3fe8c..45bea6d94 100644 --- a/apps/common/message/backends/utils.py +++ b/apps/common/message/backends/utils.py @@ -8,12 +8,12 @@ from common.message.backends import exceptions as exce logger = get_logger(__name__) -def digest(corpid, corpsecret): +def digest(corp_id, corp_secret): md5 = hashlib.md5() - md5.update(corpid.encode()) - md5.update(corpsecret.encode()) - digest = md5.hexdigest() - return digest + md5.update(corp_id.encode()) + md5.update(corp_secret.encode()) + dist = md5.hexdigest() + return dist def update_values(default: dict, others: dict): diff --git a/apps/common/message/backends/wecom/__init__.py b/apps/common/message/backends/wecom/__init__.py index 8ba593d2c..730ebcbf6 100644 --- a/apps/common/message/backends/wecom/__init__.py +++ b/apps/common/message/backends/wecom/__init__.py @@ -47,9 +47,9 @@ class WeComRequests(BaseRequest): invalid_token_errcodes = (ErrorCode.INVALID_TOKEN,) def __init__(self, corpid, corpsecret, agentid, timeout=None): - self._corpid = corpid - self._corpsecret = corpsecret - self._agentid = agentid + self._corpid = corpid or '' + self._corpsecret = corpsecret or '' + self._agentid = agentid or '' super().__init__(timeout=timeout) @@ -79,9 +79,9 @@ class WeCom(RequestMixin): """ def __init__(self, corpid, corpsecret, agentid, timeout=None): - self._corpid = corpid - self._corpsecret = corpsecret - self._agentid = agentid + self._corpid = corpid or '' + self._corpsecret = corpsecret or '' + self._agentid = agentid or '' self._requests = WeComRequests( corpid=corpid, diff --git a/apps/common/utils/common.py b/apps/common/utils/common.py index 6662e0f8b..7c449b0f0 100644 --- a/apps/common/utils/common.py +++ b/apps/common/utils/common.py @@ -275,7 +275,7 @@ class Time: last = timestamp -def bulk_get(d, *keys, default=None): +def bulk_get(d, keys, default=None): values = [] for key in keys: values.append(d.get(key, default)) diff --git a/apps/common/utils/jumpserver.py b/apps/common/utils/jumpserver.py index 1ae806366..402cee610 100644 --- a/apps/common/utils/jumpserver.py +++ b/apps/common/utils/jumpserver.py @@ -1,5 +1,6 @@ from django.core.cache import cache from django.shortcuts import reverse +from django.shortcuts import redirect from .random import random_string @@ -8,6 +9,17 @@ __all__ = ['FlashMessageUtil'] class FlashMessageUtil: + """ + 跳转到通用msg页面 + message_data: { + 'title': '', + 'message': '', + 'error': '', + 'redirect_url': '', + 'confirm_button': '', + 'cancel_url': '' + } + """ @staticmethod def get_key(code): key = 'MESSAGE_{}'.format(code) @@ -29,3 +41,8 @@ class FlashMessageUtil: def gen_message_url(cls, message_data): code = cls.get_message_code(message_data) return reverse('common:flash-message') + f'?code={code}' + + @classmethod + def gen_and_redirect_to(cls, message_data): + url = cls.gen_message_url(message_data) + return redirect(url) diff --git a/apps/common/views.py b/apps/common/views.py index 79d628248..4b0987da7 100644 --- a/apps/common/views.py +++ b/apps/common/views.py @@ -20,21 +20,21 @@ class FlashMessageMsgView(TemplateView): if not message_data: return HttpResponse('Message code error') - title, message, redirect_url, confirm_button, cancel_url = bulk_get( - message_data, 'title', 'message', 'redirect_url', 'confirm_button', 'cancel_url' - ) + items = ('title', 'message', 'error', 'redirect_url', 'confirm_button', 'cancel_url') + title, msg, error, redirect_url, confirm_btn, cancel_url = bulk_get(message_data, items) interval = message_data.get('interval', 3) auto_redirect = message_data.get('auto_redirect', True) has_cancel = message_data.get('has_cancel', False) context = { 'title': title, - 'messages': message, + 'message': msg, + 'error': error, 'interval': interval, 'redirect_url': redirect_url, 'auto_redirect': auto_redirect, - 'confirm_button': confirm_button, + 'confirm_button': confirm_btn, 'has_cancel': has_cancel, 'cancel_url': cancel_url, } - return self.render_to_response(context) \ No newline at end of file + return self.render_to_response(context) diff --git a/apps/settings/api/dingtalk.py b/apps/settings/api/dingtalk.py index bbbfc28a8..abb28e9da 100644 --- a/apps/settings/api/dingtalk.py +++ b/apps/settings/api/dingtalk.py @@ -4,7 +4,7 @@ from rest_framework.exceptions import APIException from rest_framework import status from django.utils.translation import gettext_lazy as _ -from settings.models import Setting +from django.conf import settings from common.permissions import IsSuperUser from common.message.backends.dingtalk import DingTalk @@ -19,24 +19,19 @@ class DingTalkTestingAPI(GenericAPIView): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) - dingtalk_appkey = serializer.validated_data['DINGTALK_APPKEY'] - dingtalk_agentid = serializer.validated_data['DINGTALK_AGENTID'] - dingtalk_appsecret = serializer.validated_data.get('DINGTALK_APPSECRET') - - if not dingtalk_appsecret: - secret = Setting.objects.filter(name='DINGTALK_APPSECRET').first() - if secret: - dingtalk_appsecret = secret.cleaned_value - - dingtalk_appsecret = dingtalk_appsecret or '' + app_key = serializer.validated_data['DINGTALK_APPKEY'] + agent_id = serializer.validated_data['DINGTALK_AGENTID'] + app_secret = serializer.validated_data.get('DINGTALK_APPSECRET') \ + or settings.DINGTALK_APPSECRET \ + or '' try: - dingtalk = DingTalk(appid=dingtalk_appkey, appsecret=dingtalk_appsecret, agentid=dingtalk_agentid) + dingtalk = DingTalk(appid=app_key, appsecret=app_secret, agentid=agent_id) dingtalk.send_text(['test'], 'test') return Response(status=status.HTTP_200_OK, data={'msg': _('Test success')}) except APIException as e: - try: + if 'errmsg' in e.detail: error = e.detail['errmsg'] - except: + else: error = e.detail return Response(status=status.HTTP_400_BAD_REQUEST, data={'error': error}) diff --git a/apps/templates/flash_message_standalone.html b/apps/templates/flash_message_standalone.html index 4d8a87f4d..463d6c00e 100644 --- a/apps/templates/flash_message_standalone.html +++ b/apps/templates/flash_message_standalone.html @@ -6,21 +6,18 @@ {% block content %}
- {% if errors %} -

-

- {{ errors }} +

+ {% if error %} +

+ {{ error }}
-

- {% endif %} - - {% if messages %} -

+ {% else %}

- {{ messages|safe }} + {{ message|safe }}
-

- {% endif %} + {% endif %} +

+
{% if has_cancel %}
@@ -44,17 +41,19 @@ {% block custom_foot_js %}