From bcc555d55d62c0d5ce7b0faeb383ce288810d90d Mon Sep 17 00:00:00 2001 From: Feng <suxuefeng20@gmail.com> Date: Thu, 18 Jul 2019 19:29:27 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=8A=9F=E8=83=BD=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- odoo_sms/controllers/sms_login.py | 136 ++++-------------------------- odoo_sms/models/res_user.py | 128 +++++++++++++++++++++++++++- 2 files changed, 145 insertions(+), 119 deletions(-) diff --git a/odoo_sms/controllers/sms_login.py b/odoo_sms/controllers/sms_login.py index 022f91d..7d725e4 100644 --- a/odoo_sms/controllers/sms_login.py +++ b/odoo_sms/controllers/sms_login.py @@ -190,18 +190,6 @@ def create_record(self, user_phone, service, sms_sid, code, timeout): }) return record - def generate_random_numbers(self, length_size): - """ - 生成指定位数的随机数字字符串 - :param length_size: - :return: - """ - numbers = "" - for i in range(length_size): - ch = chr(random.randrange(ord('0'), ord('9') + 1)) - numbers += ch - return numbers - @http.route('/web/check/sms/verification/code', type='http', auth="none") def check_verification_code(self, **kw): """ @@ -222,7 +210,6 @@ def check_verification_code(self, **kw): record.sudo().write({'state': 'invalid'}) return json.dumps({'state': False, 'msg': "验证码已失效!请重新获取!"}) records.sudo().write({'state': 'invalid'}) - return self._web_post_login(phone) def _web_post_login(self, phone): @@ -252,15 +239,11 @@ def _web_post_login(self, phone): if user.odoo_sms_token: password = base64.b64decode(user.odoo_sms_token).decode(encoding='utf-8', errors='strict') else: - # 发送修改密码的短信至手机 - result = self._send_change_password_sms(login, login, phone) - if not result['state']: - return json.dumps({ - 'state': False, - 'msg': "抱歉,由于系统发送修改密码通知短信不成功,操作回退!请联系管理员确认;具体错误Error:{}".format(result['msg']) - }) - user.sudo().write({'password': login}) - password = login + try: + user.sudo().write({'password': login}) + password = login + except Exception as e: + return json.dumps({'state': False, 'msg': "登录失败,具体原因为;{}".format(str(e))}) try: uid = request.session.authenticate(request.session.db, login, password) if uid is not False: @@ -271,101 +254,6 @@ def _web_post_login(self, phone): except Exception as e: return json.dumps({'state': False, 'msg': "登录失败!原因为:{}".format(str(e))}) - def _send_change_password_sms(self, login, password, phone): - """ - 发送修改密码通知短信 - :param login: - :param password: - :param phone: - :return: - """ - services = request.env['sms.service.config'].sudo().search([('state', '=', 'open')]) - if not services: - return json.dumps({'state': False, 'msg': "短信服务平台已关闭,请联系管理员处理."}) - result = False - for service in services: - if service.sms_type == 'tencent': - result = self.send_change_pwd_sms_by_tencent(login, password, service, phone) - logging.info(result) - if result['state']: - break - elif service.sms_type == 'ali': - logging.info("正在使用阿里云短信平台") - result = self.send_change_pwd_sms_by_aliyun(login, password, service, phone) - logging.info(result) - if result['state']: - break - if result['state']: - return {"state": True, 'msg': "通知短信已发送"} - else: - return {"state": False, 'msg': result['msg']} - - def send_change_pwd_sms_by_tencent(self, login, password, service, phone): - """ - 腾讯云发送修改密码通知短信 - 腾讯云短信通知模板: "你好: 你的账户信息已发生改变,新的账户信息为:用户名:{1},密码:{2},请及时登录系统并进行修改!" - :param login: - :param password: - :param service: - :param phone: - :return: - """ - template_id, sms_sign, timeout = self._get_config_template(service, 'change_pwd') - if not template_id or not sms_sign or not timeout: - return {"state": False, 'msg': "在(短信服务配置)中没有找到可用于(修改密码通知模板)的模板,请联系管理员设置!"} - s_sender = SmsSingleSender(service.app_id, service.app_key) - params = [login, password] - try: - result = s_sender.send_with_param(86, phone, template_id, params, sign=sms_sign, extend="", ext="") - logging.info("tencent-sms-change-pwd:{}".format(result)) - if result['result'] == 0: - return {"state": True} - else: - return {"state": False, 'msg': "腾讯云发送修改密码短信失败!,Error:{}".format(result['errmsg'])} - except Exception as e: - return {"state": False, 'msg': "腾讯云发送修改密码短信失败,Error:{}".format(str(e))} - - def send_change_pwd_sms_by_aliyun(self, login, password, service, phone): - """ - 通过阿里云发送修改密码通知短信 - 短信模板为: "你好: 你的账户信息已发生改变,新的账户信息为:用户名:${name},密码:${pwd},请及时登录系统查看或进行修改!" - :param login: - :param password: - :param service: - :param phone: - :return: - """ - client = AcsClient(service.app_id, service.app_key, 'default') - com_request = CommonRequest() - com_request.set_accept_format('json') - com_request.set_domain("dysmsapi.aliyuncs.com") - com_request.set_method('POST') - com_request.set_protocol_type('https') - com_request.set_version('2017-05-25') - com_request.set_action_name('SendSms') - template_id, sms_sign, timeout = self._get_config_template(service, 'change_pwd') - if not template_id or not sms_sign or not timeout: - return {"state": False, 'msg': "在(短信服务配置)中没有找到可用于(登录时发送验证码)的模板,请联系管理员设置!"} - com_request.add_query_param('PhoneNumbers', phone) - com_request.add_query_param('SignName', sms_sign) - com_request.add_query_param('TemplateCode', template_id) - param_data = { - 'name': login, - 'pwd': password - } - param_json = json.dumps(param_data) - com_request.add_query_param('TemplateParam', param_json) - try: - cli_response = client.do_action_with_exception(com_request) - cli_res = json.loads(str(cli_response, encoding='utf-8')) - logging.info("ali-sms-result: {}".format(cli_res)) - if cli_res['Code'] == 'OK': - return {"state": True} - else: - return {"state": False, 'msg': "阿里云发送修改密码短信失败!,Error:{}".format(cli_res['Message'])} - except Exception as e: - return {"state": False, 'msg': "阿里云发送修改密码短信失败,Error:{}".format(str(e))} - def _get_config_template(self, service, tem_type): """ 获取可发送验证码的短信模板、签名、超时时长 @@ -382,4 +270,16 @@ def _get_config_template(self, service, tem_type): template_id = template.template_id sms_sign = template.sign_name timeout = template.timeout - return template_id, sms_sign, timeout \ No newline at end of file + return template_id, sms_sign, timeout + + def generate_random_numbers(self, length_size): + """ + 生成指定位数的随机数字字符串 + :param length_size: + :return: + """ + numbers = "" + for i in range(length_size): + ch = chr(random.randrange(ord('0'), ord('9') + 1)) + numbers += ch + return numbers \ No newline at end of file diff --git a/odoo_sms/models/res_user.py b/odoo_sms/models/res_user.py index 72d96a2..8577198 100644 --- a/odoo_sms/models/res_user.py +++ b/odoo_sms/models/res_user.py @@ -18,9 +18,13 @@ # ################################################################################### import base64 +import json import logging from odoo import api, fields, models -from odoo.exceptions import UserError +from odoo.exceptions import UserError, ValidationError +from qcloudsms_py import SmsSingleSender +from aliyunsdkcore.client import AcsClient +from aliyunsdkcore.request import CommonRequest _logger = logging.getLogger(__name__) @@ -44,6 +48,128 @@ def constrains_login_phone(self): raise UserError("抱歉!{}手机号码已被'{}'占用,请解除或更换号码!".format(res.login_phone, users[0].name)) def _set_password(self): + """ + 修改密码后,短信通知到用户 + :return: + """ for user in self: user.sudo().write({'odoo_sms_token': base64.b64encode(user.password.encode('utf-8'))}) + if user.login_phone: + result = self.send_change_password_sms(user.login, user.password, user.login_phone) + if not result['state']: + raise ValidationError("抱歉,系统发送修改密码通知短信不成功,请检查原因;Error:{}".format(result['msg'])) super(ResUsers, self)._set_password() + + def send_change_password_sms(self, login, password, phone): + """ + 发送修改密码通知短信 + :param login: + :param password: + :param phone: + :return: + """ + services = self.env['sms.service.config'].sudo().search([('state', '=', 'open')]) + if not services: + return {'state': False, 'msg': "短信服务平台已关闭,请联系管理员处理"} + result = False + for service in services: + if service.sms_type == 'tencent': + result = self._send_change_pwd_sms_by_tencent(login, password, service, phone) + logging.info(result) + if result['state']: + break + elif service.sms_type == 'ali': + logging.info("正在使用阿里云短信平台") + result = self._send_change_pwd_sms_by_aliyun(login, password, service, phone) + logging.info(result) + if result['state']: + break + if result['state']: + return {"state": True, 'msg': "通知短信已发送"} + else: + return {"state": False, 'msg': result['msg']} + + def _send_change_pwd_sms_by_tencent(self, login, password, service, phone): + """ + 腾讯云发送修改密码通知短信 + 腾讯云短信通知模板: "你好: 你的账户信息已发生改变,新的账户信息为:用户名:{1},密码:{2},请及时登录系统并进行修改!" + :param login: + :param password: + :param service: + :param phone: + :return: + """ + template_id, sms_sign, timeout = self._get_sms_config_template(service, 'change_pwd') + if not template_id or not sms_sign or not timeout: + return {"state": False, 'msg': "在(短信服务配置)中没有找到可用于(修改密码通知模板)的模板,请联系管理员设置!"} + s_sender = SmsSingleSender(service.app_id, service.app_key) + params = [login, password] + try: + result = s_sender.send_with_param(86, phone, template_id, params, sign=sms_sign, extend="", ext="") + logging.info("tencent-sms-change-pwd:{}".format(result)) + if result['result'] == 0: + return {"state": True} + else: + return {"state": False, 'msg': "腾讯云发送修改密码短信失败!,Error:{}".format(result['errmsg'])} + except Exception as e: + return {"state": False, 'msg': "腾讯云发送修改密码短信失败,Error:{}".format(str(e))} + + def _send_change_pwd_sms_by_aliyun(self, login, password, service, phone): + """ + 通过阿里云发送修改密码通知短信 + 短信模板为: "你好: 你的账户信息已发生改变,新的账户信息为:用户名:${name},密码:${pwd},请及时登录系统查看或进行修改!" + :param login: + :param password: + :param service: + :param phone: + :return: + """ + client = AcsClient(service.app_id, service.app_key, 'default') + com_request = CommonRequest() + com_request.set_accept_format('json') + com_request.set_domain("dysmsapi.aliyuncs.com") + com_request.set_method('POST') + com_request.set_protocol_type('https') + com_request.set_version('2017-05-25') + com_request.set_action_name('SendSms') + template_id, sms_sign, timeout = self._get_sms_config_template(service, 'change_pwd') + if not template_id or not sms_sign or not timeout: + return {"state": False, 'msg': "在(短信服务配置)中没有找到可用于(登录时发送验证码)的模板,请联系管理员设置!"} + com_request.add_query_param('PhoneNumbers', phone) + com_request.add_query_param('SignName', sms_sign) + com_request.add_query_param('TemplateCode', template_id) + param_data = { + 'name': login, + 'pwd': password + } + param_json = json.dumps(param_data) + com_request.add_query_param('TemplateParam', param_json) + try: + cli_response = client.do_action_with_exception(com_request) + cli_res = json.loads(str(cli_response, encoding='utf-8')) + logging.info("ali-sms-result: {}".format(cli_res)) + if cli_res['Code'] == 'OK': + return {"state": True} + else: + return {"state": False, 'msg': "阿里云发送修改密码短信失败!,Error:{}".format(cli_res['Message'])} + except Exception as e: + return {"state": False, 'msg': "阿里云发送修改密码短信失败,Error:{}".format(str(e))} + + @api.model + def _get_sms_config_template(self, service, tem_type): + """ + 获取可发送验证码的短信模板、签名、超时时长 + :param service: + :param tem_type: + :return: + """ + template_id = 0 # 短信模板ID,需要在短信控制台中申请 + sms_sign = "" # 短信签名 + timeout = "" # 超时时长 {2} + # 获取可发送验证码的短信模板和签名 + for template in service.template_ids: + if template.used_for == tem_type: + template_id = template.template_id + sms_sign = template.sign_name + timeout = template.timeout + return template_id, sms_sign, timeout \ No newline at end of file