From 7a45f4d12992a9c310d2ca1750706cd5b15dd11e Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 13 Sep 2021 20:15:59 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E7=9F=AD=E4=BF=A1=20?= =?UTF-8?q?(#6826)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 优化短信 * refactor: 适配新的短信模板配置 Co-authored-by: ibuler Co-authored-by: xinwen --- apps/common/message/backends/sms/__init__.py | 43 ++++--------------- apps/common/message/backends/sms/alibaba.py | 2 +- apps/common/message/backends/sms/tencent.py | 2 +- apps/jumpserver/conf.py | 6 ++- apps/jumpserver/settings/auth.py | 14 ------ apps/jumpserver/settings/custom.py | 17 ++++++++ apps/locale/zh/LC_MESSAGES/django.mo | Bin 94647 -> 94691 bytes apps/locale/zh/LC_MESSAGES/django.po | 2 +- apps/settings/api/alibaba_sms.py | 9 ++-- apps/settings/api/tencent_sms.py | 9 ++-- apps/settings/serializers/auth/sms.py | 25 +++++------ apps/settings/serializers/other.py | 10 +++-- 12 files changed, 58 insertions(+), 81 deletions(-) diff --git a/apps/common/message/backends/sms/__init__.py b/apps/common/message/backends/sms/__init__.py index 760b55407..3eaf6fecf 100644 --- a/apps/common/message/backends/sms/__init__.py +++ b/apps/common/message/backends/sms/__init__.py @@ -11,34 +11,6 @@ from common.exceptions import JMSException logger = get_logger(__file__) -class SMS_MESSAGE(TextChoices): - """ - 定义短信的各种消息类型,会存到类似 `ALIBABA_SMS_SIGN_AND_TEMPLATES` settings 里 - - { - 'verification_code': {'sign_name': 'Jumpserver', 'template_code': 'SMS_222870834'}, - ... - } - """ - - """ - 验证码签名和模板。模板例子: - `您的验证码:${code},您正进行身份验证,打死不告诉别人!` - 其中必须包含 `code` 变量 - """ - VERIFICATION_CODE = 'verification_code' - - def get_sign_and_tmpl(self, config: dict): - try: - data = config[self] - return data['sign_name'], data['template_code'] - except KeyError as e: - raise JMSException( - code=f'{settings.SMS_BACKEND}_sign_and_tmpl_bad', - detail=_('Invalid SMS sign and template: {}').format(e) - ) - - class BACKENDS(TextChoices): ALIBABA = 'alibaba', _('Alibaba cloud') TENCENT = 'tencent', _('Tencent cloud') @@ -49,11 +21,7 @@ class BaseSMSClient: 短信终端的基类 """ - SIGN_AND_TMPL_SETTING_FIELD: str - - @property - def sign_and_tmpl(self): - return getattr(settings, self.SIGN_AND_TMPL_SETTING_FIELD, {}) + SIGN_AND_TMPL_SETTING_FIELD_PREFIX: str @classmethod def new_from_settings(cls): @@ -86,5 +54,12 @@ class SMS: ) def send_verify_code(self, phone_number, code): - sign_name, template_code = SMS_MESSAGE.VERIFICATION_CODE.get_sign_and_tmpl(self.client.sign_and_tmpl) + sign_name = getattr(settings, f'{self.client.SIGN_AND_TMPL_SETTING_FIELD_PREFIX}_VERIFY_SIGN_NAME') + template_code = getattr(settings, f'{self.client.SIGN_AND_TMPL_SETTING_FIELD_PREFIX}_VERIFY_TEMPLATE_CODE') + + if not (sign_name and template_code): + raise JMSException( + code='verify_code_sign_tmpl_invalid', + detail=_('SMS verification code signature or template invalid') + ) return self.send_sms([phone_number], sign_name, template_code, OrderedDict(code=code)) diff --git a/apps/common/message/backends/sms/alibaba.py b/apps/common/message/backends/sms/alibaba.py index b664f4401..2c5532c4f 100644 --- a/apps/common/message/backends/sms/alibaba.py +++ b/apps/common/message/backends/sms/alibaba.py @@ -15,7 +15,7 @@ logger = get_logger(__file__) class AlibabaSMS(BaseSMSClient): - SIGN_AND_TMPL_SETTING_FIELD = 'ALIBABA_SMS_SIGN_AND_TEMPLATES' + SIGN_AND_TMPL_SETTING_FIELD_PREFIX = 'ALIBABA' @classmethod def new_from_settings(cls): diff --git a/apps/common/message/backends/sms/tencent.py b/apps/common/message/backends/sms/tencent.py index 6f796bb15..427e8b7dd 100644 --- a/apps/common/message/backends/sms/tencent.py +++ b/apps/common/message/backends/sms/tencent.py @@ -20,7 +20,7 @@ class TencentSMS(BaseSMSClient): """ https://cloud.tencent.com/document/product/382/43196#.E5.8F.91.E9.80.81.E7.9F.AD.E4.BF.A1 """ - SIGN_AND_TMPL_SETTING_FIELD = 'TENCENT_SMS_SIGN_AND_TEMPLATES' + SIGN_AND_TMPL_SETTING_FIELD_PREFIX = 'TENCENT' @classmethod def new_from_settings(cls): diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 74fd3b708..a2e96966f 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -249,12 +249,14 @@ class Config(dict): 'ALIBABA_ACCESS_KEY_ID': '', 'ALIBABA_ACCESS_KEY_SECRET': '', - 'ALIBABA_SMS_SIGN_AND_TEMPLATES': {}, + 'ALIBABA_VERIFY_SIGN_NAME': '', + 'ALIBABA_VERIFY_TEMPLATE_CODE': '', 'TENCENT_SECRET_ID': '', 'TENCENT_SECRET_KEY': '', 'TENCENT_SDKAPPID': '', - 'TENCENT_SMS_SIGN_AND_TEMPLATES': {}, + 'TENCENT_VERIFY_SIGN_NAME': '', + 'TENCENT_VERIFY_TEMPLATE_CODE': '', 'OTP_VALID_WINDOW': 2, 'OTP_ISSUER_NAME': 'JumpServer', diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index ac9fdb631..048c76a39 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -122,21 +122,7 @@ AUTH_FEISHU = CONFIG.AUTH_FEISHU FEISHU_APP_ID = CONFIG.FEISHU_APP_ID FEISHU_APP_SECRET = CONFIG.FEISHU_APP_SECRET -# SMS auth -SMS_ENABLED = CONFIG.SMS_ENABLED -SMS_BACKEND = CONFIG.SMS_BACKEND -SMS_TEST_PHONE = CONFIG.SMS_TEST_PHONE -# Alibaba -ALIBABA_ACCESS_KEY_ID = CONFIG.ALIBABA_ACCESS_KEY_ID -ALIBABA_ACCESS_KEY_SECRET = CONFIG.ALIBABA_ACCESS_KEY_SECRET -ALIBABA_SMS_SIGN_AND_TEMPLATES = CONFIG.ALIBABA_SMS_SIGN_AND_TEMPLATES - -# TENCENT -TENCENT_SECRET_ID = CONFIG.TENCENT_SECRET_ID -TENCENT_SECRET_KEY = CONFIG.TENCENT_SECRET_KEY -TENCENT_SDKAPPID = CONFIG.TENCENT_SDKAPPID -TENCENT_SMS_SIGN_AND_TEMPLATES = CONFIG.TENCENT_SMS_SIGN_AND_TEMPLATES # Other setting TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 0ef447621..91973d1b2 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -132,3 +132,20 @@ LOGIN_REDIRECT_MSG_ENABLED = CONFIG.LOGIN_REDIRECT_MSG_ENABLED CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS = CONFIG.CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS XRDP_ENABLED = CONFIG.XRDP_ENABLED + + +# SMS enabled +SMS_ENABLED = CONFIG.SMS_ENABLED +SMS_BACKEND = CONFIG.SMS_BACKEND +SMS_TEST_PHONE = CONFIG.SMS_TEST_PHONE + +# Alibaba +ALIBABA_ACCESS_KEY_ID = CONFIG.ALIBABA_ACCESS_KEY_ID +ALIBABA_ACCESS_KEY_SECRET = CONFIG.ALIBABA_ACCESS_KEY_SECRET +ALIBABA_SMS_SIGN_AND_TEMPLATES = CONFIG.ALIBABA_SMS_SIGN_AND_TEMPLATES + +# TENCENT +TENCENT_SECRET_ID = CONFIG.TENCENT_SECRET_ID +TENCENT_SECRET_KEY = CONFIG.TENCENT_SECRET_KEY +TENCENT_SDKAPPID = CONFIG.TENCENT_SDKAPPID +TENCENT_SMS_SIGN_AND_TEMPLATES = CONFIG.TENCENT_SMS_SIGN_AND_TEMPLATES diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index f5ecd7eb66a64394363cb7f5c80594275a9d3ff7..ac63b99c8c24f6c791f7e6b876df9af52f406174 100644 GIT binary patch delta 26880 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