class BaseService(object): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools() def return_error(self, error_code, error_msg=None, status_code=200): self.request_tools.return_error(error_code, error_msg, status_code)
class BaseService(object): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools() def return_error(self, error_code, error_msg=None, status_code=200): self.request_tools.return_error(error_code, error_msg, status_code) @staticmethod def check_args(keys, args, judge=None, judge_args=(None, "")): """ 校验参数在字典中是否存在,并且判断是否为空 :param keys: 必填字段列表,可以是字符串也可以是列表 :param args: :param judge: 是否开启 是否为空的 校验, 默认不开启 :param judge_args: 校验值类型列表, 默认包含 None "", 可以自定义 :return: True 校验通过 """ must_keys = [] if isinstance(keys, str): must_keys.append(keys) else: must_keys = keys for key in keys: if not judge: if key not in args: return False else: if key in args: if args.get(key) in judge_args: return False else: return False return True
class BaseService(object): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.engine = None self.Session = None self.init_session() self.request_tools = RequestTools() def init_session(self): cf = config.get_db_config() connect_string = 'mysql+pymysql://%s:%s@%s:%s/%s' % ( cf['user'], cf['password'], cf['host'], cf['port'], cf['db']) print("connect_string:", connect_string) self.engine = create_engine(connect_string) self.Session = sessionmaker() self.Session.configure(bind=self.engine) @contextmanager def session_scope(self): session = self.Session() try: yield session except InvalidUsageException as error: session.rollback() raise error except Exception as error: session.rollback() raise error finally: session.close() def return_error(self, err_code, error_msg=None, status_code=400): self.request_tools.return_error(err_code, error_msg, status_code)
def __init__(self, *args, **kwargs): super().__init__() self.request_tools = RequestTools() self.engine = None self.Session = None self.aes_share_key = None self.aes_nonce = None self.init_session() if 'aes_share_key' in kwargs: self.aes_share_key = kwargs['aes_share_key'] if 'aes_nonce' in kwargs: self.aes_nonce = kwargs['aes_nonce']
def transfer_to_platform(url, data=None, method="post", headers=None): request_body = {} if data is None else data request_headers = {} if headers is None else headers if "Content-Type" not in request_headers: request_headers["Content-Type"] = "application/json" request_body = json.dumps(request_body) response = requests.request(method, url, data=request_body, headers=request_headers) if response.status_code != 200: RequestTools().return_error(10019) response_json = response.content.decode('utf-8') response_dict = json.loads(response_json) return response_dict
def check_args(*args, **kwargs): log_string = func.__name__ + " was called" print(log_string) if location > len(args) - 1: print(str(location) + " beyong args length ") else: if check_type == "mobile": user_mobile = args[location] regexp = r"^(1)\d{10}$" # 开始验证 if re.match(regexp, user_mobile): return func(*args, **kwargs) else: RequestTools().return_error(20012)
def get_return_msg(self, data=None, category=True): if category: if self.return_type == 'str': return FormatOutput.make_body_return_success(data) else: return data else: if self.return_type == 'str': return FormatOutput.make_body_return_error( error_desc="System desc " + data) elif self.return_type == 'html': value = '' if self.default_value is None else self.default_value resp = make_response(value) resp.headers['Content-Type'] = 'text/html' return resp elif self.return_type == 'return_error_by_header': request_tools = RequestTools() request_tools.return_error_by_header(int(self.default_value)) else: # self.return_type == 'return_error': request_tools = RequestTools() request_tools.return_error(int(self.default_value))
def get_return_msg(self): if self.return_type == 'str': if self.default_value is None: return '' else: return self.default_value elif self.return_type == 'return_error': request_tools = RequestTools() request_tools.return_error(int(self.default_value)) elif self.return_type == 'html': value = '' if self.default_value is None else self.default_value resp = make_response(value) resp.headers['Content-Type'] = 'text/html' return resp elif self.return_type == 'return_error_by_header': request_tools = RequestTools() request_tools.return_error_by_header(int(self.default_value)) # 出现报错,最后的方案是直接return_error终止程序 request_tools = RequestTools() request_tools.return_error(10000)
class BaseController(Resource): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools() def get_argument_dict(self, must_keys=None, format_str=False, format_keys=True, format_eval=True, verify_timeliness=True, verify_key=None, expire_time=None, check_token=True, invariable_key=False, api_type="invest"): """ :param must_keys: must_keys=["aa", "bb"] 判断出入列表里的值,是否在请求参数里,没有报错 :param format_str: 是否需要把所有int类型,强转成字符串 :param format_eval: 是否开启 把字符串 '["a","b"]' '{"a":1,"b":"1"}' 强转回list dict :param format_keys: 是否开启 把key的值 转为全小写 :param verify_timeliness: 是否做请求时效校验,默认需要校验 :param verify_key: 请求时效校验所包含的key,默认不包含key的校验 :param expire_time: 请求实效校验的时效 :param check_token: 是否检查token,存在token,则必须检查 :param invariable_key: 用户未登录情况下,使用指定密钥解密 :param api_type: invest/投资用户前端和移动端 borrow/管理后台 :return: """ # 获取参数字典 ip = request.remote_addr white_list = get_white_list() if ip not in white_list: self.return_error(100000) request_args = {} if verify_timeliness and verify_key and expire_time and invariable_key: try: request_args = self.decrypt_request_content( check_token=check_token, api_type=api_type) print("request_args解析后:\n", request_args) except Exception as error: raise_logger(str(error)) self.return_error(10006, error_msg="解析参数出现错误,请重新尝试") else: request_args = self.get_request_content() request_args = formate_args(request_args, format_str, format_keys, format_eval) # 判断必填字段 if must_keys: for key in must_keys: if key not in request_args: raise_logger("请求缺少 [%s] 参数" % key, error_code=20003) self.return_error(20003) return request_args # def get_bank_argument_dict(self, format_str=False, format_keys=True, # format_eval=True): # """ # :param must_keys: must_keys=["aa", "bb"] 判断出入列表里的值,是否在请求参数里,没有报错 # :param format_str: 是否需要把所有int类型,强转成字符串 # :param format_eval: 是否开启 把字符串 '["a","b"]' '{"a":1,"b":"1"}' 强转回list dict # :param format_keys: 是否开启 把key的值 转为全小写 # :return: # """ # # 获取参数字典 # request_args = self.get_request_content() # args = formate_args(request_args, format_str, format_keys, format_eval) # cfca_helper = CfcaHelper() # print("银行返回的原装参数=========") # print(request_args) # return cfca_helper.res_data(args) def return_error(self, error_code, error_msg=None, status_code=200): self.request_tools.return_error(error_code, error_msg, status_code) def decrypt_request_content(self, check_token, api_type): """ 解析用户请求参数 :param check_token: 是否对token进行校验(针对注册登录提交信息的接口) :return: """ content = self.get_request_content() user_mobile = content.get("user_mobile") # 临时添加,防止加密 version = request.headers.get('Version', "1.0") if version == "1.0": return content if "data" in content.keys(): print("存在key为data的数据,开始使用用户绑定密钥对数据进行解密") encrypt_data = content.get("data") ds = DecryptService() decrypt_data = ds.decrypt_request_content_with_invariable_key( user_mobile, encrypt_data, check_token, api_type) content.pop("data") content = dict(content, **decrypt_data) return content def get_request_content(self): """ 获取请求参数,如果参数中有data字段,直接返回data字段内容 :return: """ request_type = request.headers.get('Content-Type') user_mobile = request.headers.get('User-Mobile', default="") if request_type: content_type = request_type.split(';')[0].lower() if content_type == "application/json": print("application/json") request_args = request.get_json() else: # multipart/form-data print("multipart/form-data") request_args = request.form request_args = request_args.to_dict() else: print("None Content-Type") request_args = {} for i in request.values.dicts: for k, v in i.items(): request_args[k] = v print("request_args解析前:\n", request_args) request_args.setdefault("user_mobile", user_mobile) return request_args def make_html_response(self, value): resp = make_response(value) resp.headers['Content-Type'] = 'text/html' return resp
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools()
def get_return_msg(self): if self.return_type == 'str': if self.default_value is None: return '' else: return self.default_value elif self.return_type == 'return_error': request_tools = RequestTools() request_tools.return_error(int(self.default_value)) elif self.return_type == 'return_error_by_header': request_tools = RequestTools() request_tools.return_error_by_header(int(self.default_value)) # 出现报错,最后的方案是直接return_error终止程序 request_tools = RequestTools() request_tools.return_error(10000)
class AutomaticReleaseInstance(object): """ 自动发布game实例 """ slog = Slog("automatic_release_script") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools() def automatic_release_instance(self): # now = int(time.time()) # time_struct = time.localtime(now) # str_time = time.strftime("%Y-%m-%d %H:%M:%S", time_struct) str_time = get_utc_now() with MysqlTools().session_scope() as session: template_result = session.query(GameDigitalTemplateModel). \ filter(GameDigitalTemplateModel.template_status == 1, GameDigitalTemplateModel.auto_release == 1).all() if len(template_result) > 0: for row in template_result: btc_usdt_rate = get_exchange_rate( row.reward_token)['price'] ceiling = row.need_ceiling floor = row.need_floor email_config = get_sms_email('common') if email_config == {}: self.return_error(35034) send_email_config = get_sms_email("send_email_config") subject = email_config['email_subject'] if btc_usdt_rate > ceiling or btc_usdt_rate < floor: self.slog.info("instantiation fail. rate is ", str(btc_usdt_rate)) self.slog.info("game template id is ", str(row._id)) # 警告邮件 send_mail( "game自动实例化失败, GAME模板id:" + str(row._id) + ",奖励币种价格:" + str(btc_usdt_rate), send_email_config['user'], send_email_config['pwd'], email_config['email'], subject, send_email_config['smtp_server'], send_email_config['smtp_port']) else: template_id = row._id instance_list = session.query(GameDigitalInstanceModel). \ filter(GameDigitalInstanceModel.status == 0, GameDigitalInstanceModel.template_id == template_id).all() if len(instance_list) <= 0: phase_prefix = row.phase_prefix need = btc_usdt_rate * row.reward_quantity * ( (100 + row.exceeded_ratio) / 100) game_serial = generate_phase(str(phase_prefix)) digital_instance_model = GameDigitalInstanceModel( template_id=template_id, game_serial=game_serial, game_title=row.game_title, bet_token=row.bet_token, bet_unit=row.bet_unit, support_token=row.support_token, reward_token=row.reward_token, reward_quantity=row.reward_quantity, handling_fee=row.handling_fee, game_describe=row.game_describe, experience=row.experience, merge_threshold=row.merge_threshold, release_time=str_time, need=int(need), status=0, release_type=1, chain_status=0) # if create_all_bet_number(game_serial, int(need)) != 2000: # self.slog.info("create all bet number fail") if not GameNumberSetService().createNumbers( { "game_serial": game_serial, "total": int(need) }): self.slog.info("create all bet number fail") self.return_error(40015) session.add(digital_instance_model) session.flush() try: # 发布信息上链 if BlockChainInfoService( ).insert_block_chain_info( '', str(digital_instance_model._id), 2, { "instance_id": digital_instance_model._id, "template_id": template_id, "game_serial": game_serial, "support_token": row.support_token, "bet_token": row.bet_token, "bet_unit": row.bet_unit, "reward_token": row.reward_token, "reward_quantity": row.reward_quantity, "handling_fee": str(row.handling_fee), "game_describe": row.game_describe, "release_time": str_time.strftime("%Y-%m-%d %H:%M:%S"), "status": 0, "need": int(need), "release_type": 0, }): digital_instance_model.chain_status = 1 self.slog.info( "insert_block_chain_info success") else: self.slog.info( "insert_block_chain_info fail") except Exception as e: self.slog.info("insert_block_chain_info fail") self.slog.info(f"Exception: {e}") # self.slog.info("automatic_release_instance fail") # session.rollback() session.commit() # send_mail("game自动实例化成功, GAME模板id:" + str(template_id) + ",奖励币种价格:" + str(btc_usdt_rate), # send_email_config['user'], send_email_config['pwd'], # email_config['email'], # subject, send_email_config['smtp_server'], send_email_config['smtp_port']) self.slog.info( "automatic_release_instance success") def return_error(self, error_code, error_msg=None, status_code=200): self.request_tools.return_error(error_code, error_msg, status_code)
class BaseController(Resource): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools() self.logger = logging.getLogger('rs') def return_error(self, err_code, error_msg=None, status_code=400): self.request_tools.return_error(err_code, error_msg, status_code) # 正式环境测试,开所有校验的函数头 def get_argument_dict(self, must_keys=None, format_str=False, format_keys=True, format_eval=True, verify_timeliness=True, encrypt=True, check_token=True, invariable_key=True, check_form_token=False, is_transfer=False, api_type=_USER_TYPE_INVEST, request_type=_REQUEST_TYPE_LOGIN, decode_by_inner=_DECODE_TYPE_DEFAULT, check_user_id=False): """ :param must_keys: 必须含有的key :param format_str: str格式化 :param format_keys: keys格式化 :param format_eval: :param verify_timeliness: 校验时效性 :param encrypt: 是否加密 :param check_token: 是否校验token :param invariable_key: 是否采用默认的sharekey解密 :param check_form_token: 是否校验表单的随机字符串 :param is_transfer: 是否是通过usercenter传递数据到其他平台 :param api_type: 访问接口的用户类型 :param request_type: 请求的类型:注册、登陆前、登陆后 :param decode_by_inner: 是否采用内网的sharekey解析 :param check_user_id: 是否校验userid的正确性 :return: """ env = get_conf('env') if env == 'dev' and get_conf('close_all_aes'): # 测试环境,关所有校验的函数头 verify_timeliness = False encrypt = False check_token = False invariable_key = False check_form_token = False try: # 1. 校验时效性 if not verify_timeliness: request_header = request.headers source = request_header.get("Source", _SOURCE_TYPE_1) else: ''' # 校验实效性,需要header中存在如下参数 Timestamp, Signature, Nonce, Source ''' redis_tools = RedisTools() request_header = request.headers # 1.0 判断时间是否在请求限制时间内 timestamp = request_header.get("Timestamp", '0') df_timestamp = abs(int(time.time()) - int(timestamp)) if df_timestamp > 6000 or df_timestamp < 0: self.return_error(10005) # 2.0 检查signature是否在redis中,防止重复请求 c_signature = request_header.get("Signature") if redis_tools.exists(c_signature): self.return_error(10003) # 3.0 验证c_signature合理性 nonce = request_header.get("Nonce", '') source = request_header.get("Source", _SOURCE_TYPE_1) if nonce == '' or source == '': self.return_error(10006) s_signature = sha256_hex( str(timestamp) + str(nonce) + str(source)) self.logger.info('check signature ' + str(timestamp) + ' ' + str(nonce) + ' ' + str(source) + ' ' + str(s_signature) + ' ' + str(c_signature)) if s_signature != c_signature: self.return_error(10004) # 4.0 将c_signature存到redis中 redis_tools.set(name=c_signature, value="c_signature", ex=60) content = self.get_request_content() share_key, nonce = None, None # 2.1 不解密解析,仅开发环境生效 if not encrypt: decrypt_content = content if 'data' in content and isinstance(content['data'], dict): for k, v in content['data'].items(): content[k] = v del content['data'] if check_token: # 2.0 获取用户信息 ts = ApiTokenService( aes_share_key=share_key, aes_nonce=nonce).check_access_token_by_user_id( decrypt_content, api_type) if not ts: self.return_error(10035) else: if 'data' not in content.keys(): self.return_error(10008) delete_user_id = False if is_transfer and content['user_mobile'] == '': invariable_key = False check_token = False decode_by_inner = _DECODE_TYPE_DEFAULT delete_user_id = True # 2.2 使用指定秘钥解密 if invariable_key: decrypt_content, share_key, nonce = self.decrypt_request_content( content, check_token=check_token, api_type=api_type, request_type=request_type, check_user_id=check_user_id, source=source) else: decrypt_content, share_key, nonce = self.decrypt_request_content_with_invariable_key( content, check_token=check_token, api_type=api_type, decode_by_inner=decode_by_inner, source=source) if delete_user_id: decrypt_content['user_id'] = '' # 3 规范入参 request_args = formate_args(decrypt_content, format_str, format_keys, format_eval) self.logger.info("request_args解析后:" + str(request_args)) # 4 确保表单有效性 if check_form_token: if 'form_token' not in request_args: self.return_error(10046) vcode_service = VcodeService(aes_share_key=share_key, aes_nonce=nonce) # 2.0 校验token vcode_service.check_register_signature( request_args['form_token']) request_args.pop('form_token') # 5 校验是否包含规定的参数 if must_keys: for key in must_keys: if key not in request_args: error_msg = "请求缺少 [%s] 参数" % key self.return_error(10048, error_msg=error_msg) return request_args, share_key, nonce except InvalidUsageException as error: raise_logger(error.error_msg, error_code=error.error_code) raise error except OperateUsageException as error: raise error except Exception as error: raise_logger(str(error), error_code=10022) self.return_error(10022) def get_request_content(self, set_default=True): """ 获取请求参数,如果参数中有data字段,直接返回data字段内容 :return: """ request_type = request.headers.get('Content-Type') user_mobile = request.headers.get('User-Mobile', default="") source = request.headers.get("Source", _SOURCE_TYPE_1) if user_mobile != "": user_mobile = str(base64.b64decode( bytes(user_mobile, encoding="utf8")), encoding="utf8") access_token = request.headers.get('Authorization', default="") if request_type: content_type = request_type.split(';')[0].lower() if content_type == "application/json": self.logger.info("Content-Type: application/json") request_args = request.get_json() else: # multipart/form-data self.logger.info("Content-Type: multipart/form-data") request_args = request.form request_args = request_args.to_dict() else: self.logger.info("Content-Type: None") request_args = {} for i in request.values.dicts: for k, v in i.items(): request_args[k] = v if set_default: request_args.setdefault("user_mobile", user_mobile) request_args.setdefault("access_token", access_token) request_args.setdefault("source", source) return request_args def decrypt_request_content(self, content, check_token=True, api_type=_USER_TYPE_INVEST, request_type=_REQUEST_TYPE_LOGIN, check_user_id=False, source=_SOURCE_TYPE_1): """ 解析用户请求参数 :param check_token: 是否对token进行校验(针对注册登录提交信息的接口) :return: """ user_mobile = content.get("user_mobile") self.logger.info("存在key为data的数据,开始使用用户绑定密钥对数据进行解密") encrypt_data = content.get("data") ds = DecryptService() decrypt_data, share_key, nonce = ds.decrypt_users_data( user_mobile, encrypt_data, check_token=check_token, api_type=api_type, request_type=request_type, check_user_id=check_user_id, source=source) content.pop("data") content = dict(content, **decrypt_data) return content, share_key, nonce def decrypt_request_content_with_invariable_key( self, content, check_token=True, api_type=_USER_TYPE_INVEST, decode_by_inner=_DECODE_TYPE_DEFAULT, source=_SOURCE_TYPE_1): """ 使用不变key,解密请求参数(针对注册,登录获取sqlt和验证用户是否注册的接口) :return: """ self.logger.info("存在key为data的数据,开始使用未用户绑定密钥对数据进行解密") encrypt_data = content.get("data") ds = DecryptService() decrypt_data, share_key, nonce = ds.decrypt_request_content_with_invariable_key( encrypt_data, check_token, api_type, decode_by_inner=decode_by_inner) content.pop("data") content = dict(content, **decrypt_data) return content, share_key, nonce def check_form_token(self, token): vcode_service = VcodeService() # 2.0 校验token return vcode_service.check_register_signature(token, direct_error=False)
class BaseController(Resource): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools() def return_error(self, error_code, error_msg=None, status_code=200): self.request_tools.return_error(error_code, error_msg, status_code) def get_argument_dict(self, must_keys=None, format_str=False, format_keys=True, format_eval=True, check_form_token=False, time_key_list=None): """ :param must_keys: must_keys=["aa", "bb"] 判断出入列表里的值,是否在请求参数里,没有报错 :param format_str: 是否需要把所有int类型,强转成字符串 :param format_eval: 是否开启 把字符串 '["a","b"]' '{"a":1,"b":"1"}' 强转回list dict :param format_keys: 是否开启 把key的值 转为全小写 :param check_form_token: 是否校验表单中的随机字符串,所有会修改数据的请求,都应该校验!! :param time_key_list: 转换时区的校验时间key补充字段列表 :return: """ # 获取参数字典 request_args = self.get_request_content() request_args = formate_args(request_args, format_str, format_keys, format_eval) if get_env() != 'dev' and check_form_token: if 'form_token' not in request_args: self.return_error(10018) check_url = get_user_center_conf()[get_env( )]['base_url'] + '/transfer/' + str(request_args['form_token']) check_result = transfer_to_platform(check_url) if not check_result: self.return_error(10018) request_args.pop('form_token') # 判断必填字段 if must_keys: for key in must_keys: if key not in request_args: raise_logger("请求缺少 [%s] 参数" % key, lv="error") self.return_error(20003) return self.timezone_transform(request_args, time_key_list) def timezone_transform(self, request_args, other_listen_key_list=None): """ 转换请求参数时间 :param request_args: :param other_listen_key_list: :return: """ listen_key_list = _REQUEST_KEY_LIST if isinstance(other_listen_key_list, list): listen_key_list = list(set(listen_key_list + other_listen_key_list)) if request.method == "POST": try: timezone = int(request.headers.get('TimeZone', '')) except: self.return_error(10021) timezone = 0 request_args["timezone"] = timezone request_args = recursive_dict_args(request_args, listen_key_list, time_transform_from_zone, timezone) return request_args def utctime_to_localtime(self, response_args, other_listen_key_list=None): """ 服务端utc时间转换给客户端相应时区的时间 :param response_args: :param other_listen_key_list: :return: """ if not isinstance(response_args, dict): return response_args listen_key_list = _RESPONSE_KEY_LIST if isinstance(other_listen_key_list, list): listen_key_list = list(set(listen_key_list + other_listen_key_list)) try: timezone = int(request.headers.get('TimeZone', '')) if timezone == "" and request.method == "POST": self.return_error(10021) except: timezone = 0 self.return_error(10021) response_args = recursive_dict_args(response_args, listen_key_list, time_transform_from_zone, -timezone) return response_args def get_request_content(self): """ 获取请求参数,如果参数中有data字段,直接返回data字段内容 :return: """ request_type = request.headers.get('Content-Type') if request_type: content_type = request_type.split(';')[0].lower() if content_type == "application/json": request_args = request.get_json() else: # multipart/form-data request_args = request.form request_args = request_args.to_dict() else: request_args = {} for i in request.values.dicts: for k, v in i.items(): request_args[k] = v return request_args def make_html_response(self, value): resp = make_response(value) resp.headers['Content-Type'] = 'text/html' return resp
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request_tools = RequestTools() self.logger = logging.getLogger('rs')
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.engine = None self.Session = None self.init_session() self.request_tools = RequestTools()
class BaseService(object): def __init__(self, *args, **kwargs): super().__init__() self.request_tools = RequestTools() self.engine = None self.Session = None self.aes_share_key = None self.aes_nonce = None self.init_session() if 'aes_share_key' in kwargs: self.aes_share_key = kwargs['aes_share_key'] if 'aes_nonce' in kwargs: self.aes_nonce = kwargs['aes_nonce'] def return_error(self, err_code, error_msg=None, status_code=400): # 前后端交互端报错,不需要加密给客户端 self.request_tools.return_error(err_code, error_msg, status_code) @FormateOutput(default_value=10007, return_type='return_error') def init_session(self): conf = get_mysql_config() connect_string = 'mysql+pymysql://%s:%s@%s:%s/%s?charset=utf8mb4' % (conf['user'], conf['password'], conf['host'], conf['port'], conf['db']) self.engine = create_engine(connect_string) self.Session = sessionmaker() self.Session.configure(bind=self.engine) @contextmanager def session_scope(self): session = self.Session() try: yield session except InvalidUsageException as error: session.rollback() raise error except FundamentalErrorException as error: session.rollback() raise error except Exception as error: session.rollback() raise error finally: session.close() def check_mobile(self, user_mobile): if not check_mobile(user_mobile): self.return_error(30200) def check_mobile_all(self, user_mobile): if not check_mobile_all(user_mobile): self.return_error(30200) def check_email(self, email): if not check_email(email): self.return_error(30218) def get_user_key_nonce(self, user_type, user_id=None, request_type=_REQUEST_TYPE_LOGIN): share_key = _SHARE_KEY nonce = _NONCE if user_type == _USER_TYPE_NONE: pass elif user_type == _USER_TYPE_INNER: share_key = _INNER_SHARE_KEY nonce = _INNER_NONCE else: with self.session_scope() as session: key_salt = session.query(KeySaltModel).filter(KeySaltModel.user_id == user_id, KeySaltModel.user_type == user_type, KeySaltModel.deleted == False, KeySaltModel.request_type == request_type, ).first() if key_salt is not None: share_key = key_salt.share_key nonce = key_salt.nonce return share_key, nonce def return_aes_error(self, err_code, error_msg=None, status_code=200): # 业务逻辑报错,需要加密返回给客户端 # self.aes_share_key, self.aes_nonce参数为空,则return_aes_error不加密,应用场景如服务端直接的通信 self.request_tools.return_operate_error(err_code, error_msg, status_code, self.aes_share_key, self.aes_nonce) def check_source(self, register_by, user_source): allow_register_by = get_conf('register_by') if register_by not in allow_register_by: self.return_aes_error(30215) if user_source not in KeySaltModel.get_all_source_type(): self.return_aes_error(30216) return True def send_aws_sms(self, mobile, vcode, template=None, mobile_country_code=None): aws_config = get_aws_config() if mobile_country_code is None: mobile = '+86' + str(mobile) else: mobile = str(mobile_country_code) + str(mobile) if template is None: send_message = '验证码为:' + str(vcode) else: send_message = str(template) send_result, response_message = send_aws_sms( aws_config['aws_access_key_id'], aws_config['aws_secret_access_key'], mobile, send_message ) with self.session_scope() as session: q = SmsMessageModel( send_message=json.dumps({ 'aws_access_key_id': aws_config['aws_access_key_id'], 'aws_secret_access_key': aws_config['aws_secret_access_key'], 'mobile': mobile, 'send_message': send_message, }), response_message=json.dumps(response_message), gateway='aws', ) session.add(q) session.commit() if not send_result: # self.return_aes_error(30056) return False return True def get_nick_name(self, user_model, session=None): if session is None: with self.session_scope() as session: return self.__get_nick_name(user_model, session) else: return self.__get_nick_name(user_model, session) def __get_nick_name(self, user_model, session): while True: nick_name = get_random_str(k=8, except_list=['0']) one_user = self.__check_nick_name(user_model, nick_name, session) if not one_user: break return nick_name def check_nick_name(self, user_model, nick_name, session=None): if session is None: with self.session_scope() as session: return self.__check_nick_name(user_model, nick_name, session) else: return self.__check_nick_name(user_model, nick_name, session) def __check_nick_name(self, user_model, nick_name, session): user = session.query(user_model).filter( user_model.nick_name == nick_name, user_model.deleted == False, ).first() if user: return user else: return False def send_ZT_sms(self, mobile, vcode, template=None, mobile_country_code=None): # 发送国短信 if mobile_country_code is not None and mobile_country_code not in ['+86', '0086']: return False zt_config = get_zt_config() user_name = zt_config['user_name'] password = zt_config['password'] send_url = zt_config['send_url'] time_str = datetime.datetime.fromtimestamp(int(time.time()), pytz.timezone('Asia/Shanghai')).strftime('%Y%m%d%H%M%S') send_password = encrypt_md5(encrypt_md5(password) + time_str) if template is None: send_message = '验证码为:' + str(vcode) else: send_message = str(template) request_data = { 'username': user_name, 'tkey': time_str, 'password': send_password, 'mobile': mobile, 'content': send_message, } response_data = transfer_to_platform( send_url, data=request_data, headers={ 'Content-Type': 'application/x-www-form-urlencoded', }, method="post", decode_type='str', ) with self.session_scope() as session: q = SmsMessageModel( send_message=json.dumps({ 'request_data': request_data, 'mobile': mobile, 'send_message': send_message, }), response_message=json.dumps(response_data), gateway='ZT', ) session.add(q) session.commit() response_result = response_data.split(',') if response_result[0] == '1': return True else: return False def send_Intl_ZT_sms(self, mobile, vcode, template=None, mobile_country_code=None): # 发送国际短信 # 去除区号的+和0 mobile_country_code = mobile_country_code.replace('+', '') mobile_country_code = str(int(mobile_country_code)) zt_config = get_intl_zt_config() user_name = zt_config['user_name'] password = zt_config['password'] send_url = zt_config['send_url'] time_str = datetime.datetime.fromtimestamp(int(time.time()), pytz.timezone('Asia/Shanghai')).strftime('%Y%m%d%H%M%S') send_password = encrypt_md5(encrypt_md5(password) + time_str) if template is None: send_message = '验证码为:' + str(vcode) else: send_message = str(template) request_data = { 'username': user_name, 'tkey': time_str, 'password': send_password, 'code': mobile_country_code, 'mobile': mobile, 'content': send_message, } response_data = transfer_to_platform( send_url, data=request_data, headers={ 'Content-Type': 'application/x-www-form-urlencoded', }, method="post", decode_type='str', ) with self.session_scope() as session: q = SmsMessageModel( send_message=json.dumps({ 'request_data': request_data, 'mobile': mobile, 'send_message': send_message, }), response_message=json.dumps(response_data), gateway='Intl_ZT', ) session.add(q) session.commit() response_result = response_data.split(',') if response_result[0] == '1': return True else: return False def send_gateway_sms(self, mobile, vcode, template=None, mobile_country_code=None): import threading t = threading.Thread(target=self.__send_gateway_sms, args=(mobile, vcode, template, mobile_country_code,)) t.start() return True def __send_gateway_sms(self, mobile, vcode, template=None, mobile_country_code=None): # 按照顺序尝试发送短信 result = self.send_aws_sms(mobile, vcode, template=template, mobile_country_code=mobile_country_code) if result is True: return True if mobile_country_code is None: mobile_country_code = '+86' if mobile_country_code in ['+86', '0086']: result = self.send_ZT_sms(mobile, vcode, template=template, mobile_country_code=mobile_country_code) if result is True: return True else: result = self.send_Intl_ZT_sms(mobile, vcode, template=template, mobile_country_code=mobile_country_code) if result is True: return True with self.session_scope() as session: q = SmsMessageModel( send_message=json.dumps({ 'mobile': mobile, 'vcode': vcode, 'template': template, 'mobile_country_code': mobile_country_code, }), response_message=json.dumps({}), gateway='send_fail', ) session.add(q) session.commit() return False def send_mail(self, mail_body, user, pwd, to, subject, smtp_server, smtp_port): import threading t = threading.Thread(target=send_mail, args=(mail_body, user, pwd, to, subject, smtp_server, smtp_port,)) t.start() return True