jumpserver/apps/settings/serializers/auth/sms.py

120 lines
6.1 KiB
Python
Raw Normal View History

2023-05-24 09:32:57 +00:00
from django.db import models
2023-07-24 03:52:25 +00:00
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
2023-07-24 03:52:25 +00:00
from common.sdk.sms import BACKENDS
from common.serializers.fields import EncryptedField, PhoneField
from common.validators import PhoneValidator
__all__ = [
'BaseSMSSettingSerializer',
'SMSSettingSerializer', 'AlibabaSMSSettingSerializer', 'TencentSMSSettingSerializer',
2023-05-24 09:32:57 +00:00
'HuaweiSMSSettingSerializer', 'CMPP2SMSSettingSerializer', 'CustomSMSSettingSerializer',
]
2021-09-09 12:59:26 +00:00
class SMSSettingSerializer(serializers.Serializer):
SMS_ENABLED = serializers.BooleanField(default=False, label=_('Enable SMS'))
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')
)
2021-09-09 13:11:57 +00:00
class SignTmplPairSerializer(serializers.Serializer):
SIGN_NAME = serializers.CharField(max_length=256, required=True, label=_('Signature'))
TEMPLATE_CODE = serializers.CharField(max_length=256, required=True, label=_('Template code'))
2021-09-09 12:59:26 +00:00
class BaseSMSSettingSerializer(serializers.Serializer):
PREFIX_TITLE = _('SMS')
2023-07-24 03:52:25 +00:00
SMS_TEST_PHONE = PhoneField(
validators=[PhoneValidator()], required=False, allow_blank=True, allow_null=True, label=_('Test phone')
)
def to_representation(self, instance):
data = super().to_representation(instance)
2021-09-09 12:59:26 +00:00
# data['SMS_BACKEND'] = self.fields['SMS_BACKEND'].default
return data
class AlibabaSMSSettingSerializer(BaseSMSSettingSerializer):
ALIBABA_ACCESS_KEY_ID = serializers.CharField(max_length=256, required=True, label='Access Key ID')
ALIBABA_ACCESS_KEY_SECRET = EncryptedField(
max_length=256, required=False, label='Access Key Secret',
)
ALIBABA_VERIFY_SIGN_NAME = serializers.CharField(max_length=256, required=True, label=_('Signature'))
ALIBABA_VERIFY_TEMPLATE_CODE = serializers.CharField(max_length=256, required=True, label=_('Template code'))
class TencentSMSSettingSerializer(BaseSMSSettingSerializer):
TENCENT_SECRET_ID = serializers.CharField(max_length=256, required=True, label='Secret ID')
TENCENT_SECRET_KEY = EncryptedField(max_length=256, required=False, label='Secret Key')
TENCENT_SDKAPPID = serializers.CharField(max_length=256, required=True, label='SDK APP ID')
TENCENT_VERIFY_SIGN_NAME = serializers.CharField(max_length=256, required=True, label=_('Signature'))
TENCENT_VERIFY_TEMPLATE_CODE = serializers.CharField(max_length=256, required=True, label=_('Template code'))
class HuaweiSMSSettingSerializer(BaseSMSSettingSerializer):
HUAWEI_APP_KEY = serializers.CharField(max_length=256, required=True, label='App Key')
HUAWEI_APP_SECRET = EncryptedField(max_length=256, required=False, label='App Secret')
HUAWEI_SMS_ENDPOINT = serializers.CharField(max_length=1024, required=True, label=_('App Access Address'))
HUAWEI_SIGN_CHANNEL_NUM = serializers.CharField(max_length=1024, required=True, label=_('Signature channel number'))
HUAWEI_VERIFY_SIGN_NAME = serializers.CharField(max_length=256, required=True, label=_('Signature'))
HUAWEI_VERIFY_TEMPLATE_CODE = serializers.CharField(max_length=256, required=True, label=_('Template code'))
class CMPP2SMSSettingSerializer(BaseSMSSettingSerializer):
CMPP2_HOST = serializers.CharField(max_length=256, required=True, label=_('Host'))
CMPP2_PORT = serializers.IntegerField(default=7890, label=_('Port'))
CMPP2_SP_ID = serializers.CharField(max_length=128, required=True, label=_('Enterprise code(SP id)'))
CMPP2_SP_SECRET = EncryptedField(max_length=256, required=False, label=_('Shared secret(Shared secret)'))
CMPP2_SRC_ID = serializers.CharField(max_length=256, required=False, label=_('Original number(Src id)'))
CMPP2_SERVICE_ID = serializers.CharField(max_length=256, required=True, label=_('Business type(Service id)'))
CMPP2_VERIFY_SIGN_NAME = serializers.CharField(max_length=256, required=True, label=_('Signature'))
CMPP2_VERIFY_TEMPLATE_CODE = serializers.CharField(
max_length=69, required=True, label=_('Template'),
help_text=_('Template need contain {code} and Signature + template length does not exceed 67 words. '
'For example, your verification code is {code}, which is valid for 5 minutes. '
'Please do not disclose it to others.')
)
def validate(self, attrs):
sign_name = attrs.get('CMPP2_VERIFY_SIGN_NAME', '')
template_code = attrs.get('CMPP2_VERIFY_TEMPLATE_CODE', '')
if template_code.find('{code}') == -1:
raise serializers.ValidationError(_('The template needs to contain {code}'))
if len(sign_name + template_code) > 65:
# 保证验证码内容在一条短信中(长度小于70字), 签名两边的括号和空格占3个字再减去2个即可(验证码占用4个但占位符6个
raise serializers.ValidationError(_('Signature + Template must not exceed 65 words'))
return attrs
2023-05-24 09:32:57 +00:00
class CustomSMSSettingSerializer(BaseSMSSettingSerializer):
class RequestType(models.TextChoices):
get = 'get', 'Get'
post = 'post', 'Post'
CUSTOM_SMS_URL = serializers.URLField(required=True, label=_("URL"))
CUSTOM_SMS_API_PARAMS = serializers.JSONField(
2023-05-24 09:32:57 +00:00
label=_('Parameters'), default={'phone_number': '{phone_number}', 'code': '{code}'}
)
CUSTOM_SMS_REQUEST_METHOD = serializers.ChoiceField(
default=RequestType.get, choices=RequestType.choices, label=_("Request method")
)
def validate(self, attrs):
2023-05-24 09:32:57 +00:00
need_params = {'{phone_numbers}', '{code}'}
params = attrs.get('CUSTOM_SMS_API_PARAMS', {})
# 这里用逗号分隔是保证需要的参数必须是完整的,不能分开在不同的参数中首位相连
params_string = ','.join(params.values())
for param in need_params:
if param not in params_string:
raise serializers.ValidationError(
2023-05-24 09:32:57 +00:00
_('The value in the parameter must contain %s') % ','.join(need_params)
)
return attrs