feat: 支持自定义短信认证(文件) (#11784)

* feat: 支持自定义短信认证(文件)

* perf: 翻译

* perf: 还原注释
pull/11797/head
jiangweidong 2023-10-10 18:23:54 +08:00 committed by GitHub
parent 333746e7c4
commit 70f0f55ddb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 193 additions and 84 deletions

View File

@ -10,7 +10,7 @@ logger = get_logger(__file__)
mfa_custom_method = None
if settings.MFA_CUSTOM:
""" 保证自定义认证方法在服务运行时不能被更改,只在第一次调用时加载一次 """
""" 保证自定义方法在服务运行时不能被更改,只在第一次调用时加载一次 """
try:
mfa_custom_method_path = 'data.mfa.main.check_code'
mfa_custom_method = import_string(mfa_custom_method_path)

View File

@ -30,7 +30,7 @@ class CustomSMS(BaseSMSClient):
code=template_param.get('code'), phone_numbers=phone_numbers_str
)
logger.info(f'Custom sms send: phone_numbers={phone_numbers}param={params}')
logger.info(f'Custom sms send: phone_numbers={phone_numbers}, param={params}')
if settings.CUSTOM_SMS_REQUEST_METHOD == 'post':
action = requests.post
kwargs = {'json': params}

View File

@ -0,0 +1,50 @@
import os
from collections import OrderedDict
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from django.utils.module_loading import import_string
from common.utils import get_logger
from common.exceptions import JMSException
from jumpserver.settings import get_file_md5
from .base import BaseSMSClient
logger = get_logger(__file__)
custom_sms_method = None
SMS_CUSTOM_FILE_MD5 = settings.SMS_CUSTOM_FILE_MD5
SMS_CUSTOM_FILE_PATH = os.path.join(settings.PROJECT_DIR, 'data', 'sms', 'main.py')
if SMS_CUSTOM_FILE_MD5 == get_file_md5(SMS_CUSTOM_FILE_PATH):
try:
custom_sms_method_path = 'data.sms.main.send_sms'
custom_sms_method = import_string(custom_sms_method_path)
except Exception as e:
logger.warning('Import custom sms method failed: {}, Maybe not enabled'.format(e))
class CustomFileSMS(BaseSMSClient):
@classmethod
def new_from_settings(cls):
return cls()
@staticmethod
def need_pre_check():
return False
def send_sms(self, phone_numbers: list, template_param: OrderedDict, **kwargs):
if not callable(custom_sms_method):
raise JMSException(_('The custom sms file is invalid'))
try:
logger.info(f'Custom file sms send: phone_numbers={phone_numbers}, param={template_param}')
custom_sms_method(phone_numbers, template_param, **kwargs)
except Exception as err:
raise JMSException(_('SMS sending failed[%s]: %s') % (f"{_('Custom type')}({_('File')})", err))
client = CustomFileSMS

View File

@ -17,7 +17,8 @@ class BACKENDS(TextChoices):
TENCENT = 'tencent', _('Tencent cloud')
HUAWEI = 'huawei', _('Huawei Cloud')
CMPP2 = 'cmpp2', _('CMPP v2.0')
Custom = 'custom', _('Custom type')
CUSTOM = 'custom', _('Custom type')
CUSTOM_FILE = 'custom_file', f"{_('Custom type')}({_('File')})"
class SMS:

View File

@ -67,7 +67,7 @@ class SendAndVerifyCodeUtil(object):
return cache.get(self.key)
def __generate(self):
code = random_string(4, lower=False, upper=False)
code = random_string(settings.SMS_CODE_LENGTH, lower=False, upper=False)
self.code = code
return code

View File

@ -247,10 +247,11 @@ class Config(dict):
'AUTH_CUSTOM': False,
'AUTH_CUSTOM_FILE_MD5': '',
# Custom Config
'MFA_CUSTOM': False,
'MFA_CUSTOM_FILE_MD5': '',
'SMS_CUSTOM_FILE_MD5': '',
# 临时密码
'AUTH_TEMP_TOKEN': False,
@ -409,6 +410,7 @@ class Config(dict):
'SMS_ENABLED': False,
'SMS_BACKEND': '',
'SMS_CODE_LENGTH': 4,
'SMS_TEST_PHONE': '',
'ALIBABA_ACCESS_KEY_ID': '',
@ -439,7 +441,7 @@ class Config(dict):
'CMPP2_VERIFY_TEMPLATE_CODE': '{code}',
'CUSTOM_SMS_URL': '',
'CUSTOM_SMS_API_PARAMS': {'phone_numbers': '{phone_numbers}', 'code': '{code}'},
'CUSTOM_SMS_API_PARAMS': {'phone_numbers': '{phone_numbers}', 'content': _('The verification code is: {code}')},
'CUSTOM_SMS_REQUEST_METHOD': 'get',
# Email

View File

@ -259,6 +259,9 @@ if MFA_CUSTOM and MFA_CUSTOM_FILE_MD5 == get_file_md5(MFA_CUSTOM_FILE_PATH):
# 自定义多因子认证模块
MFA_BACKENDS.append(MFA_BACKEND_CUSTOM)
SMS_CUSTOM_FILE_MD5 = CONFIG.SMS_CUSTOM_FILE_MD5
SMS_CUSTOM_FILE_PATH = os.path.join(PROJECT_DIR, 'data', 'sms', 'main.py')
AUTHENTICATION_BACKENDS_THIRD_PARTY = [
AUTH_BACKEND_OIDC_CODE, AUTH_BACKEND_CAS,
AUTH_BACKEND_SAML2, AUTH_BACKEND_OAUTH2

View File

@ -169,6 +169,7 @@ TERMINAL_KOKO_SSH_ENABLED = CONFIG.TERMINAL_KOKO_SSH_ENABLED
# SMS enabled
SMS_ENABLED = CONFIG.SMS_ENABLED
SMS_BACKEND = CONFIG.SMS_BACKEND
SMS_CODE_LENGTH = CONFIG.SMS_CODE_LENGTH
SMS_TEST_PHONE = CONFIG.SMS_TEST_PHONE
# Alibaba
@ -186,6 +187,11 @@ TENCENT_VERIFY_SIGN_NAME = CONFIG.TENCENT_VERIFY_SIGN_NAME
TENCENT_VERIFY_TEMPLATE_CODE = CONFIG.TENCENT_VERIFY_TEMPLATE_CODE
TENCENT_SMS_SIGN_AND_TEMPLATES = CONFIG.TENCENT_SMS_SIGN_AND_TEMPLATES
# CUSTOM_SMS
CUSTOM_SMS_URL = CONFIG.CUSTOM_SMS_URL
CUSTOM_SMS_API_PARAMS = CONFIG.CUSTOM_SMS_API_PARAMS
CUSTOM_SMS_REQUEST_METHOD = CONFIG.CUSTOM_SMS_REQUEST_METHOD
# 公告
ANNOUNCEMENT_ENABLED = CONFIG.ANNOUNCEMENT_ENABLED
ANNOUNCEMENT = CONFIG.ANNOUNCEMENT

View File

@ -81,7 +81,7 @@ msgid "Collected"
msgstr "集めました"
#: accounts/const/account.py:27 accounts/serializers/account/account.py:28
#: settings/serializers/auth/sms.py:75
#: settings/serializers/auth/sms.py:79
msgid "Template"
msgstr "テンプレート"
@ -1325,7 +1325,7 @@ msgid "Script"
msgstr "脚本"
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:71
#: settings/serializers/feature.py:47 terminal/models/component/endpoint.py:13
#: terminal/serializers/applet.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:72
@ -1616,7 +1616,7 @@ msgid "Cloud"
msgstr "クラウド サービス"
#: assets/models/asset/common.py:92 assets/models/platform.py:16
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:68
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:72
#: xpack/plugins/cloud/serializers/account_attrs.py:73
msgid "Port"
msgstr "ポート"
@ -1692,7 +1692,7 @@ msgid "Proxy"
msgstr "プロキシー"
#: assets/models/automations/base.py:22 ops/models/job.py:223
#: settings/serializers/auth/sms.py:99
#: settings/serializers/auth/sms.py:103
msgid "Parameters"
msgstr "パラメータ"
@ -2892,7 +2892,7 @@ msgstr "メッセージ検証コードが無効"
#: authentication/mfa/sms.py:12 authentication/serializers/password_mfa.py:16
#: authentication/serializers/password_mfa.py:24
#: settings/serializers/auth/sms.py:28 users/forms/profile.py:104
#: settings/serializers/auth/sms.py:32 users/forms/profile.py:104
#: users/forms/profile.py:109 users/templates/users/forgot_password.html:112
#: users/views/profile/reset.py:98
msgid "SMS"
@ -3164,7 +3164,7 @@ msgstr "コードエラー"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
#: jumpserver/conf.py:447
#: jumpserver/conf.py:449
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@ -3674,6 +3674,15 @@ msgstr "SP idは6ビット"
msgid "Failed to connect to the CMPP gateway server, err: {}"
msgstr "接続ゲートウェイサーバエラー, 非: {}"
#: common/sdk/sms/custom_file.py:41
msgid "The custom sms file is invalid"
msgstr "カスタムショートメッセージファイルが無効です"
#: common/sdk/sms/custom_file.py:47
#, python-format
msgid "SMS sending failed[%s]: %s"
msgstr "ショートメッセージの送信に失敗しました[%s]: %s"
#: common/sdk/sms/endpoint.py:16
msgid "Alibaba cloud"
msgstr "アリ雲"
@ -3690,11 +3699,11 @@ msgstr "華為雲"
msgid "CMPP v2.0"
msgstr "CMPP v2.0"
#: common/sdk/sms/endpoint.py:31
#: common/sdk/sms/endpoint.py:32
msgid "SMS provider not support: {}"
msgstr "SMSプロバイダーはサポートしていません: {}"
#: common/sdk/sms/endpoint.py:53
#: common/sdk/sms/endpoint.py:54
msgid "SMS verification code signature or template invalid"
msgstr "SMS検証コードの署名またはテンプレートが無効"
@ -3765,11 +3774,15 @@ msgstr "特殊文字を含むべきではない"
msgid "The mobile phone number format is incorrect"
msgstr "携帯電話番号の形式が正しくありません"
#: jumpserver/conf.py:446
#: jumpserver/conf.py:444
msgid "The verification code is: {code}"
msgstr "認証コードは: {code}"
#: jumpserver/conf.py:448
msgid "Create account successfully"
msgstr "アカウントを正常に作成"
#: jumpserver/conf.py:448
#: jumpserver/conf.py:450
msgid "Your account has been created successfully"
msgstr "アカウントが正常に作成されました"
@ -4596,7 +4609,7 @@ msgid "View permission tree"
msgstr "権限ツリーの表示"
#: settings/api/dingtalk.py:31 settings/api/feishu.py:36
#: settings/api/sms.py:153 settings/api/vault.py:40 settings/api/wecom.py:37
#: settings/api/sms.py:160 settings/api/vault.py:40 settings/api/wecom.py:37
msgid "Test success"
msgstr "テストの成功"
@ -4624,11 +4637,11 @@ msgstr "Ldapユーザーを取得するにはNone"
msgid "Imported {} users successfully (Organization: {})"
msgstr "{} 人のユーザーを正常にインポートしました (組織: {})"
#: settings/api/sms.py:135
#: settings/api/sms.py:142
msgid "Invalid SMS platform"
msgstr "無効なショートメッセージプラットフォーム"
#: settings/api/sms.py:141
#: settings/api/sms.py:148
msgid "test_phone is required"
msgstr "携帯番号をテストこのフィールドは必須です"
@ -5034,54 +5047,58 @@ msgstr "SP プライベートキー"
msgid "SP cert"
msgstr "SP 証明書"
#: settings/serializers/auth/sms.py:16
#: settings/serializers/auth/sms.py:17
msgid "Enable SMS"
msgstr "SMSの有効化"
#: settings/serializers/auth/sms.py:18
#: settings/serializers/auth/sms.py:19
msgid "SMS provider / Protocol"
msgstr "SMSプロバイダ / プロトコル"
#: settings/serializers/auth/sms.py:23 settings/serializers/auth/sms.py:45
#: settings/serializers/auth/sms.py:53 settings/serializers/auth/sms.py:62
#: settings/serializers/auth/sms.py:73 settings/serializers/msg.py:76
#: settings/serializers/auth/sms.py:22
msgid "SMS code length"
msgstr "認証コード長"
#: settings/serializers/auth/sms.py:27 settings/serializers/auth/sms.py:49
#: settings/serializers/auth/sms.py:57 settings/serializers/auth/sms.py:66
#: settings/serializers/auth/sms.py:77 settings/serializers/msg.py:76
msgid "Signature"
msgstr "署名"
#: settings/serializers/auth/sms.py:24 settings/serializers/auth/sms.py:46
#: settings/serializers/auth/sms.py:54 settings/serializers/auth/sms.py:63
#: settings/serializers/auth/sms.py:28 settings/serializers/auth/sms.py:50
#: settings/serializers/auth/sms.py:58 settings/serializers/auth/sms.py:67
msgid "Template code"
msgstr "テンプレートコード"
#: settings/serializers/auth/sms.py:31
#: settings/serializers/auth/sms.py:35
msgid "Test phone"
msgstr "テスト電話"
#: settings/serializers/auth/sms.py:60
#: settings/serializers/auth/sms.py:64
msgid "App Access Address"
msgstr "アプリケーションアドレス"
#: settings/serializers/auth/sms.py:61
#: settings/serializers/auth/sms.py:65
msgid "Signature channel number"
msgstr "署名チャネル番号"
#: settings/serializers/auth/sms.py:69
#: settings/serializers/auth/sms.py:73
msgid "Enterprise code(SP id)"
msgstr "企業コード(SP id)"
#: settings/serializers/auth/sms.py:70
#: settings/serializers/auth/sms.py:74
msgid "Shared secret(Shared secret)"
msgstr "パスワードを共有する(Shared secret)"
#: settings/serializers/auth/sms.py:71
#: settings/serializers/auth/sms.py:75
msgid "Original number(Src id)"
msgstr "元の番号(Src id)"
#: settings/serializers/auth/sms.py:72
#: settings/serializers/auth/sms.py:76
msgid "Business type(Service id)"
msgstr "ビジネス・タイプ(Service id)"
#: settings/serializers/auth/sms.py:76
#: settings/serializers/auth/sms.py:80
#, python-brace-format
msgid ""
"Template need contain {code} and Signature + template length does not exceed "
@ -5092,24 +5109,24 @@ msgstr ""
"満です。たとえば、認証コードは{code}で、有効期間は5分です。他の人には言わない"
"でください。"
#: settings/serializers/auth/sms.py:85
#: settings/serializers/auth/sms.py:89
#, python-brace-format
msgid "The template needs to contain {code}"
msgstr "テンプレートには{code}を含める必要があります"
#: settings/serializers/auth/sms.py:88
#: settings/serializers/auth/sms.py:92
msgid "Signature + Template must not exceed 65 words"
msgstr "署名+テンプレートの長さは65文字以内"
#: settings/serializers/auth/sms.py:97
#: settings/serializers/auth/sms.py:101
msgid "URL"
msgstr "URL"
#: settings/serializers/auth/sms.py:102
#: settings/serializers/auth/sms.py:106
msgid "Request method"
msgstr "請求方法です"
#: settings/serializers/auth/sms.py:111
#: settings/serializers/auth/sms.py:117
#, python-format
msgid "The value in the parameter must contain %s"
msgstr "パラメータの値には必ず %s が含まれます"

View File

@ -80,7 +80,7 @@ msgid "Collected"
msgstr "收集"
#: accounts/const/account.py:27 accounts/serializers/account/account.py:28
#: settings/serializers/auth/sms.py:75
#: settings/serializers/auth/sms.py:79
msgid "Template"
msgstr "模板"
@ -1317,7 +1317,7 @@ msgid "Script"
msgstr "脚本"
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:67
#: settings/serializers/auth/radius.py:16 settings/serializers/auth/sms.py:71
#: settings/serializers/feature.py:47 terminal/models/component/endpoint.py:13
#: terminal/serializers/applet.py:17
#: xpack/plugins/cloud/serializers/account_attrs.py:72
@ -1608,7 +1608,7 @@ msgid "Cloud"
msgstr "云服务"
#: assets/models/asset/common.py:92 assets/models/platform.py:16
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:68
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:72
#: xpack/plugins/cloud/serializers/account_attrs.py:73
msgid "Port"
msgstr "端口"
@ -1684,7 +1684,7 @@ msgid "Proxy"
msgstr "代理"
#: assets/models/automations/base.py:22 ops/models/job.py:223
#: settings/serializers/auth/sms.py:99
#: settings/serializers/auth/sms.py:103
msgid "Parameters"
msgstr "参数"
@ -2862,7 +2862,7 @@ msgstr "短信验证码校验失败"
#: authentication/mfa/sms.py:12 authentication/serializers/password_mfa.py:16
#: authentication/serializers/password_mfa.py:24
#: settings/serializers/auth/sms.py:28 users/forms/profile.py:104
#: settings/serializers/auth/sms.py:32 users/forms/profile.py:104
#: users/forms/profile.py:109 users/templates/users/forgot_password.html:112
#: users/views/profile/reset.py:98
msgid "SMS"
@ -3132,7 +3132,7 @@ msgstr "代码错误"
#: authentication/templates/authentication/_msg_reset_password_code.html:9
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
#: jumpserver/conf.py:447
#: jumpserver/conf.py:449
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@ -3628,6 +3628,15 @@ msgstr "SP_id 为6位"
msgid "Failed to connect to the CMPP gateway server, err: {}"
msgstr "连接网关服务器错误,错误:{}"
#: common/sdk/sms/custom_file.py:41
msgid "The custom sms file is invalid"
msgstr "自定义短信文件无效"
#: common/sdk/sms/custom_file.py:47
#, python-format
msgid "SMS sending failed[%s]: %s"
msgstr "短信发送失败[%s]: %s"
#: common/sdk/sms/endpoint.py:16
msgid "Alibaba cloud"
msgstr "阿里云"
@ -3644,11 +3653,11 @@ msgstr "华为云"
msgid "CMPP v2.0"
msgstr "CMPP v2.0"
#: common/sdk/sms/endpoint.py:31
#: common/sdk/sms/endpoint.py:32
msgid "SMS provider not support: {}"
msgstr "短信服务商不支持:{}"
#: common/sdk/sms/endpoint.py:53
#: common/sdk/sms/endpoint.py:54
msgid "SMS verification code signature or template invalid"
msgstr "短信验证码签名或模版无效"
@ -3719,11 +3728,15 @@ msgstr "不能包含特殊字符"
msgid "The mobile phone number format is incorrect"
msgstr "手机号格式不正确"
#: jumpserver/conf.py:446
#: jumpserver/conf.py:444
msgid "The verification code is: {code}"
msgstr "验证码为: {code}"
#: jumpserver/conf.py:448
msgid "Create account successfully"
msgstr "创建账号成功"
#: jumpserver/conf.py:448
#: jumpserver/conf.py:450
msgid "Your account has been created successfully"
msgstr "你的账号已创建成功"
@ -4543,7 +4556,7 @@ msgid "View permission tree"
msgstr "查看授权树"
#: settings/api/dingtalk.py:31 settings/api/feishu.py:36
#: settings/api/sms.py:153 settings/api/vault.py:40 settings/api/wecom.py:37
#: settings/api/sms.py:160 settings/api/vault.py:40 settings/api/wecom.py:37
msgid "Test success"
msgstr "测试成功"
@ -4571,11 +4584,11 @@ msgstr "获取 LDAP 用户为 None"
msgid "Imported {} users successfully (Organization: {})"
msgstr "成功导入 {} 个用户 ( 组织: {} )"
#: settings/api/sms.py:135
#: settings/api/sms.py:142
msgid "Invalid SMS platform"
msgstr "无效的短信平台"
#: settings/api/sms.py:141
#: settings/api/sms.py:148
msgid "test_phone is required"
msgstr "测试手机号 该字段是必填项。"
@ -4980,54 +4993,58 @@ msgstr "SP 密钥"
msgid "SP cert"
msgstr "SP 证书"
#: settings/serializers/auth/sms.py:16
#: settings/serializers/auth/sms.py:17
msgid "Enable SMS"
msgstr "启用 SMS"
#: settings/serializers/auth/sms.py:18
#: settings/serializers/auth/sms.py:19
msgid "SMS provider / Protocol"
msgstr "短信服务商 / 协议"
#: settings/serializers/auth/sms.py:23 settings/serializers/auth/sms.py:45
#: settings/serializers/auth/sms.py:53 settings/serializers/auth/sms.py:62
#: settings/serializers/auth/sms.py:73 settings/serializers/msg.py:76
#: settings/serializers/auth/sms.py:22
msgid "SMS code length"
msgstr "验证码长度"
#: settings/serializers/auth/sms.py:27 settings/serializers/auth/sms.py:49
#: settings/serializers/auth/sms.py:57 settings/serializers/auth/sms.py:66
#: settings/serializers/auth/sms.py:77 settings/serializers/msg.py:76
msgid "Signature"
msgstr "签名"
#: settings/serializers/auth/sms.py:24 settings/serializers/auth/sms.py:46
#: settings/serializers/auth/sms.py:54 settings/serializers/auth/sms.py:63
#: settings/serializers/auth/sms.py:28 settings/serializers/auth/sms.py:50
#: settings/serializers/auth/sms.py:58 settings/serializers/auth/sms.py:67
msgid "Template code"
msgstr "模板"
#: settings/serializers/auth/sms.py:31
#: settings/serializers/auth/sms.py:35
msgid "Test phone"
msgstr "测试手机号"
#: settings/serializers/auth/sms.py:60
#: settings/serializers/auth/sms.py:64
msgid "App Access Address"
msgstr "应用地址"
#: settings/serializers/auth/sms.py:61
#: settings/serializers/auth/sms.py:65
msgid "Signature channel number"
msgstr "签名通道号"
#: settings/serializers/auth/sms.py:69
#: settings/serializers/auth/sms.py:73
msgid "Enterprise code(SP id)"
msgstr "企业代码(SP id)"
#: settings/serializers/auth/sms.py:70
#: settings/serializers/auth/sms.py:74
msgid "Shared secret(Shared secret)"
msgstr "共享密码(Shared secret)"
#: settings/serializers/auth/sms.py:71
#: settings/serializers/auth/sms.py:75
msgid "Original number(Src id)"
msgstr "原始号码(Src id)"
#: settings/serializers/auth/sms.py:72
#: settings/serializers/auth/sms.py:76
msgid "Business type(Service id)"
msgstr "业务类型(Service id)"
#: settings/serializers/auth/sms.py:76
#: settings/serializers/auth/sms.py:80
#, python-brace-format
msgid ""
"Template need contain {code} and Signature + template length does not exceed "
@ -5037,24 +5054,24 @@ msgstr ""
"模板需要包含 {code},并且模板+签名长度不能超过67个字。例如, 您的验证码是 "
"{code}, 有效期为5分钟。请不要泄露给其他人。"
#: settings/serializers/auth/sms.py:85
#: settings/serializers/auth/sms.py:89
#, python-brace-format
msgid "The template needs to contain {code}"
msgstr "模板需要包含 {code}"
#: settings/serializers/auth/sms.py:88
#: settings/serializers/auth/sms.py:92
msgid "Signature + Template must not exceed 65 words"
msgstr "模板+签名不能超过65个字"
#: settings/serializers/auth/sms.py:97
#: settings/serializers/auth/sms.py:101
msgid "URL"
msgstr "URL"
#: settings/serializers/auth/sms.py:102
#: settings/serializers/auth/sms.py:106
msgid "Request method"
msgstr "请求方式"
#: settings/serializers/auth/sms.py:111
#: settings/serializers/auth/sms.py:117
#, python-format
msgid "The value in the parameter must contain %s"
msgstr "参数中的值必须包含 %s"

View File

@ -2,6 +2,7 @@ import importlib
from collections import OrderedDict
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from rest_framework import status
from rest_framework.exceptions import APIException
from rest_framework.generics import ListAPIView, GenericAPIView
@ -28,7 +29,6 @@ class SMSBackendAPI(ListAPIView):
}
for b in BACKENDS.choices
]
return Response(data)
@ -39,11 +39,16 @@ class SMSTestingAPI(GenericAPIView):
'huawei': serializers.HuaweiSMSSettingSerializer,
'cmpp2': serializers.CMPP2SMSSettingSerializer,
'custom': serializers.CustomSMSSettingSerializer,
'custom_file': serializers.BaseSMSSettingSerializer,
}
rbac_perms = {
'POST': 'settings.change_sms'
}
@property
def test_code(self):
return '6' * settings.SMS_CODE_LENGTH
@staticmethod
def get_or_from_setting(key, value=''):
if not value:
@ -63,7 +68,7 @@ class SMSTestingAPI(GenericAPIView):
send_sms_params = {
'sign_name': data['ALIBABA_VERIFY_SIGN_NAME'],
'template_code': data['ALIBABA_VERIFY_TEMPLATE_CODE'],
'template_param': {'code': '666666'}
'template_param': {'code': self.test_code}
}
return init_params, send_sms_params
@ -78,7 +83,7 @@ class SMSTestingAPI(GenericAPIView):
send_sms_params = {
'sign_name': data['TENCENT_VERIFY_SIGN_NAME'],
'template_code': data['TENCENT_VERIFY_TEMPLATE_CODE'],
'template_param': OrderedDict(code='666666')
'template_param': OrderedDict(code=self.test_code)
}
return init_params, send_sms_params
@ -94,7 +99,7 @@ class SMSTestingAPI(GenericAPIView):
send_sms_params = {
'sign_name': data['HUAWEI_VERIFY_SIGN_NAME'],
'template_code': data['HUAWEI_VERIFY_TEMPLATE_CODE'],
'template_param': OrderedDict(code='666666')
'template_param': OrderedDict(code=self.test_code)
}
return init_params, send_sms_params
@ -110,16 +115,18 @@ class SMSTestingAPI(GenericAPIView):
send_sms_params = {
'sign_name': data['CMPP2_VERIFY_SIGN_NAME'],
'template_code': data['CMPP2_VERIFY_TEMPLATE_CODE'],
'template_param': OrderedDict(code='666666')
'template_param': OrderedDict(code=self.test_code)
}
return init_params, send_sms_params
@staticmethod
def get_custom_params(data):
def get_custom_params(self, data):
init_params = {}
send_sms_params = {'template_param': OrderedDict(code='666666')}
send_sms_params = {'template_param': OrderedDict(code=self.test_code)}
return init_params, send_sms_params
def get_custom_file_params(self, data):
return self.get_custom_params(data)
def get_params_by_backend(self, backend, data):
"""
返回两部分参数

View File

@ -7,6 +7,7 @@ from common.serializers.fields import EncryptedField, PhoneField
from common.validators import PhoneValidator
__all__ = [
'BaseSMSSettingSerializer',
'SMSSettingSerializer', 'AlibabaSMSSettingSerializer', 'TencentSMSSettingSerializer',
'HuaweiSMSSettingSerializer', 'CMPP2SMSSettingSerializer', 'CustomSMSSettingSerializer',
]
@ -17,6 +18,9 @@ class SMSSettingSerializer(serializers.Serializer):
SMS_BACKEND = serializers.ChoiceField(
choices=BACKENDS.choices, default=BACKENDS.ALIBABA, label=_('SMS provider / Protocol')
)
SMS_CODE_LENGTH = serializers.IntegerField(
default=4, min_value=4, max_value=16, label=_('SMS code length')
)
class SignTmplPairSerializer(serializers.Serializer):
@ -102,12 +106,14 @@ class CustomSMSSettingSerializer(BaseSMSSettingSerializer):
default=RequestType.get, choices=RequestType.choices, label=_("Request method")
)
@staticmethod
def validate(attrs):
def validate(self, attrs):
need_params = {'{phone_numbers}', '{code}'}
params = attrs.get('CUSTOM_SMS_API_PARAMS', {})
if len(set(params.values()) & need_params) != len(need_params):
raise serializers.ValidationError(
# 这里用逗号分隔是保证需要的参数必须是完整的,不能分开在不同的参数中首位相连
params_string = ','.join(params.values())
for param in need_params:
if param not in params_string:
raise serializers.ValidationError(
_('The value in the parameter must contain %s') % ','.join(need_params)
)
return attrs