示例#1
0
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)
示例#2
0
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
示例#3
0
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)
示例#4
0
    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']
示例#5
0
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))
示例#8
0
    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)
示例#9
0
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
示例#10
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.request_tools = RequestTools()
示例#11
0
    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)
示例#12
0
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')
示例#16
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.engine = None
     self.Session = None
     self.init_session()
     self.request_tools = RequestTools()
示例#17
0
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