def send_sms(self, phone_numbers: list, sign_name: str, template_code: str, template_param: dict, **kwargs): phone_numbers_str = ','.join(phone_numbers) send_sms_request = dysmsapi_20170525_models.SendSmsRequest( phone_numbers=phone_numbers_str, sign_name=sign_name, template_code=template_code, template_param=json.dumps(template_param)) try: logger.info(f'Alibaba sms send: ' f'phone_numbers={phone_numbers} ' f'sign_name={sign_name} ' f'template_code={template_code} ' f'template_param={template_param}') response = self.client.send_sms(send_sms_request) # 这里只判断是否成功,失败抛出异常 if response.body.code != 'OK': raise JMSException(detail=response.body.message, code=response.body.code) except TeaException as e: if e.code == 'SignatureDoesNotMatch': raise JMSException(code=e.code, detail=_('Signature does not match')) raise JMSException(code=e.code, detail=e.message) return response
def send_sms(self, phone_numbers: list, sign_name: str, template_code: str, template_param: OrderedDict, **kwargs): try: req = models.SendSmsRequest() # 基本类型的设置: # SDK采用的是指针风格指定参数,即使对于基本类型你也需要用指针来对参数赋值。 # SDK提供对基本类型的指针引用封装函数 # 帮助链接: # 短信控制台: https://console.cloud.tencent.com/smsv2 # sms helper: https://cloud.tencent.com/document/product/382/3773 # 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666 req.SmsSdkAppId = self.sdkappid # 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看 req.SignName = sign_name # 短信码号扩展号: 默认未开通,如需开通请联系 [sms helper] req.ExtendCode = "" # 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回 req.SessionContext = "Jumpserver" # 国际/港澳台短信 senderid: 国内短信填空,默认未开通,如需开通请联系 [sms helper] req.SenderId = "" # 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号] # 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 req.PhoneNumberSet = phone_numbers # 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 req.TemplateId = template_code # 模板参数: 若无模板参数,则设置为空 req.TemplateParamSet = list(template_param.values()) # 通过client对象调用DescribeInstances方法发起请求。注意请求方法名与请求对象是对应的。 # 返回的resp是一个DescribeInstancesResponse类的实例,与请求对象对应。 logger.info(f'Tencent sms send: ' f'phone_numbers={phone_numbers} ' f'sign_name={sign_name} ' f'template_code={template_code} ' f'template_param={template_param}') resp = self.client.SendSms(req) try: code = resp.SendStatusSet[0].Code msg = resp.SendStatusSet[0].Message except IndexError: raise JMSException(code='response_bad', detail=resp) if code.lower() != 'ok': raise JMSException(code=code, detail=msg) return resp except TencentCloudSDKException as e: raise JMSException(code=e.code, detail=e.message)
def perform_destroy(self, instance): user = instance.user role_qs = self.model.objects.filter(user=user) if role_qs.count() == 1: msg = _('{} at least one system role').format(user) raise JMSException(code='system_role_delete_error', detail=msg) return super().perform_destroy(instance)
def get_org(self): org_id = self.request.query_params.get('org_id') org = Organization.get_instance(org_id) if not org: error = ('The organization `{}` does not exist'.format(org_id)) raise JMSException(error) return org
def destroy(self, request, *args, **kwargs): instance = self.get_object() if instance.get_online_session_count() > 0: raise JMSException(code='have_online_session', detail=_('Have online sessions')) self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT)
def get_serializer_class(self): serializer_class = super().get_serializer_class() if getattr(self, 'swagger_fake_view', False): return serializer_class app_type = self.request.query_params.get('type') app_category = self.request.query_params.get('category') type_options = list(dict(models.Category.get_all_type_serializer_mapper()).keys()) category_options = list(dict(models.Category.get_category_serializer_mapper()).keys()) # ListAPIView 没有 action 属性 # 不使用method属性,因为options请求时为method为post action = getattr(self, 'action', 'list') if app_type and app_type not in type_options: raise JMSException( 'Invalid query parameter `type`, select from the following options: {}' ''.format(type_options) ) if app_category and app_category not in category_options: raise JMSException( 'Invalid query parameter `category`, select from the following options: {}' ''.format(category_options) ) if action in [ 'create', 'update', 'partial_update', 'bulk_update', 'partial_bulk_update' ] and not app_type: # action: create / update raise JMSException( 'The `{}` action must take the `type` query parameter'.format(action) ) if app_type: # action: create / update / list / retrieve / metadata attrs_cls = models.Category.get_type_serializer_cls(app_type) class_name = 'ApplicationDynamicSerializer{}'.format(app_type.title()) elif app_category: # action: list / retrieve / metadata attrs_cls = models.Category.get_category_serializer_cls(app_category) class_name = 'ApplicationDynamicSerializer{}'.format(app_category.title()) else: attrs_cls = models.Category.get_no_password_serializer_cls() class_name = 'ApplicationDynamicSerializer' cls = type(class_name, (serializer_class,), {'attrs': attrs_cls()}) return cls
def ticket(self): if getattr(self, 'swagger_fake_view', False): return None ticket_id = self.request.query_params.get('ticket_id') ticket = Ticket.all().filter(pk=ticket_id).first() if not ticket: raise JMSException( 'Not found Ticket object about `id={}`'.format(ticket_id)) return ticket
def __init__(self, backend=None): backend = backend or settings.SMS_BACKEND if backend not in BACKENDS: raise JMSException( code='sms_provider_not_support', detail=_('SMS provider not support: {}').format(backend) ) m = importlib.import_module(f'.{backend or settings.SMS_BACKEND}', __package__) self.client = m.client.new_from_settings()
def send_verify_code(self, phone_number, code): 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))
def update_serial_num_if_need(self): if self.serial_num: return try: self.serial_num = self.construct_serial_num() self.save(update_fields=('serial_num',)) except IntegrityError as e: if e.args[0] == 1062: # 虽然做了 `select_for_update` 但是每天的第一条工单仍可能造成冲突 # 但概率小,这里只报错,用户重新提交即可 raise JMSException(detail=_('Please try again'), code='please_try_again') raise e
def post(self, request): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) tencent_secret_id = serializer.validated_data['TENCENT_SECRET_ID'] tencent_secret_key = serializer.validated_data.get( 'TENCENT_SECRET_KEY') tencent_verify_sign_name = serializer.validated_data[ 'TENCENT_VERIFY_SIGN_NAME'] tencent_verify_template_code = serializer.validated_data[ 'TENCENT_VERIFY_TEMPLATE_CODE'] tencent_sdkappid = serializer.validated_data.get('TENCENT_SDKAPPID') test_phone = serializer.validated_data.get('SMS_TEST_PHONE') if not test_phone: raise JMSException(code='test_phone_required', detail=_('test_phone is required')) if not tencent_secret_key: secret = Setting.objects.filter(name='TENCENT_SECRET_KEY').first() if secret: tencent_secret_key = secret.cleaned_value tencent_secret_key = tencent_secret_key or '' try: client = TencentSMS(secret_id=tencent_secret_id, secret_key=tencent_secret_key, sdkappid=tencent_sdkappid) client.send_sms(phone_numbers=[test_phone], sign_name=tencent_verify_sign_name, template_code=tencent_verify_template_code, template_param=OrderedDict(code='test')) return Response(status=status.HTTP_200_OK, data={'msg': _('Test success')}) except APIException as e: try: error = e.detail['errmsg'] except: error = e.detail return Response(status=status.HTTP_400_BAD_REQUEST, data={'error': error})
def post(self, request): serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) alibaba_access_key_id = serializer.validated_data[ 'ALIBABA_ACCESS_KEY_ID'] alibaba_access_key_secret = serializer.validated_data.get( 'ALIBABA_ACCESS_KEY_SECRET') alibaba_verify_sign_name = serializer.validated_data[ 'ALIBABA_VERIFY_SIGN_NAME'] alibaba_verify_template_code = serializer.validated_data[ 'ALIBABA_VERIFY_TEMPLATE_CODE'] test_phone = serializer.validated_data.get('SMS_TEST_PHONE') if not test_phone: raise JMSException(code='test_phone_required', detail=_('test_phone is required')) if not alibaba_access_key_secret: secret = Setting.objects.filter( name='ALIBABA_ACCESS_KEY_SECRET').first() if secret: alibaba_access_key_secret = secret.cleaned_value alibaba_access_key_secret = alibaba_access_key_secret or '' try: client = AlibabaSMS(access_key_id=alibaba_access_key_id, access_key_secret=alibaba_access_key_secret) client.send_sms(phone_numbers=[test_phone], sign_name=alibaba_verify_sign_name, template_code=alibaba_verify_template_code, template_param={'code': 'test'}) return Response(status=status.HTTP_200_OK, data={'msg': _('Test success')}) except APIException as e: try: error = e.detail['errmsg'] except: error = e.detail return Response(status=status.HTTP_400_BAD_REQUEST, data={'error': error})
def check_category_allowed(obj): if not obj.category_is_remote_app: raise JMSException( 'The request instance(`{}`) is not of category `remote_app`'.format(obj.category) )