Ejemplo n.º 1
0
def build_response(from_id, to_id, data):
    if not data:
        return None
    msg_type = data['msg_type']
    result = {
        'FromUserName': from_id,
        'ToUserName': to_id,
        'MsgType': msg_type,
        'Tag': data.get('tag', '')
    }
    if msg_type == 'text':
        result.update({
            'Content': data['content'],
            'CreateTime': int(time.time())
        })
    elif msg_type == 'news':
        result.update({
            'ArticleCount': len(data['articles']),
            'Articles': {
                'item': []
            },
            'CreateTime': int(time.time())
        })
        for article in data['articles']:
            item = dtools.transfer(
                article,
                renames=[
                    ('title', 'Title'),
                    ('description', 'Description'),
                    ('picurl', 'PicUrl'),
                    ('url', 'Url')
                ])
            result['Articles']['item'].append(item)
    return result
Ejemplo n.º 2
0
def update_user_info(appid, openid):
    resp = yield get_user_info(appid, openid)
    if resp['err_code'] != 0:
        raise tornado.gen.Return({'err_code': resp['err_code']})
    else:
        resp['data']['appid'] = appid
        user_info = dtools.transfer(
            resp['data'], copys=[
                'uid',
                'appid',
                'openid',
                'unionid',
                'nickname',
                'subscribe',
                'sex',
                'city',
                'province',
                'country',
                'language',
                'headimgurl',
                'subscribe_time'
            ], allow_empty=False)
        user_info['fakeid'] = user_info['openid']
        wechat_storage.add_user_info(user_info)
        raise tornado.gen.Return({'err_code': 0, 'data': user_info})
Ejemplo n.º 3
0
    def get(self, siteid, out_trade_no):
        appid = self.get_argument('appid')
        appinfo = self.storage.get_app_info(appid=appid)
        if not appinfo:
            self.send_response(err_code=3201)
            raise tornado.gen.Return()

        req_data = {
            'appid': appid,
            'mch_id': appinfo.get('mch_id'),
            'transaction_id': '',
            'out_trade_no': out_trade_no
        }
        req_key = appinfo['apikey']
        security.add_sign(req_data, req_key)

        try:
            resp = yield httputils.post_dict(url=url.mch_order_query,
                                             data=req_data,
                                             data_type='xml')
        except tornado.httpclient.HTTPError:
            self.send_response(err_code=1001)
            raise tornado.gen.Return()

        resp_data = self.parse_payment_resp(resp, req_key)
        if resp_data:
            post_resp_data = dtools.transfer(resp_data,
                                             copys=[
                                                 'appid', 'openid',
                                                 'trade_state', 'out_trade_no',
                                                 'total_fee', 'transaction_id',
                                                 'time_end'
                                             ])
            self.send_response(post_resp_data)
Ejemplo n.º 4
0
    def post(self):
        req_data = dtools.transfer(self.post_args,
                                   copys=[
                                       'appid', 'result_code', 'err_code_des',
                                       'out_trade_no', 'total_fee', 'openid',
                                       'transaction_id', 'time_end'
                                   ])
        req_data['unionid'] = self.storage.get_user_info(
            appid=req_data['appid'],
            openid=req_data['openid'],
            select_key='unionid')
        attach = dict(
            [t.split('=') for t in self.post_args['attach'].split(',')])
        site_info = self.storage.get_site_info(siteid=attach['siteid'])
        req_key = site_info['sitekey']
        security.add_sign(req_data, req_key)

        try:
            resp = yield httputils.post_dict(url=site_info['pay_notify_url'],
                                             data=req_data)
        except tornado.httpclient.HTTPError:
            self.send_response(err_code=9002)
            return

        if resp.code == 200:
            try:
                resp_data = json.loads(resp.body.decode('utf8'))
                self.send_response(err_code=0 if resp_data.
                                   get('return_code') == 'SUCCESS' else 1)
            except ValueError:
                self.send_response(err_code=9101)
        else:
            self.send_response(err_code=9002)
Ejemplo n.º 5
0
def encrypt_data(data, crypter, appid):
    encrypted = {'encrypt': crypter.encrypt(dtools.dict2xml(data), appid)}
    add_sign_wechat(encrypted, key='wechat_platform')
    return dtools.transfer(
        encrypted,
        renames=[
            ('encrypt', 'Encrypt'),
            ('sign', 'MsgSignature'),
            ('timestamp', 'TimeStamp'),
            ('nonce', 'Nonce')])
Ejemplo n.º 6
0
def update_user_info(appid, openid):
    resp = yield get_user_info(appid, openid)
    if resp['err_code'] != 0:
        raise tornado.gen.Return({'err_code': resp['err_code']})
    else:
        resp['data']['appid'] = appid
        user_info = dtools.transfer(resp['data'],
                                    copys=[
                                        'uid', 'appid', 'openid', 'unionid',
                                        'nickname', 'subscribe', 'sex', 'city',
                                        'province', 'country', 'language',
                                        'headimgurl', 'subscribe_time'
                                    ],
                                    allow_empty=False)
        user_info['fakeid'] = user_info['openid']
        wechat_storage.add_user_info(user_info)
        raise tornado.gen.Return({'err_code': 0, 'data': user_info})
Ejemplo n.º 7
0
    def post(self, siteid):
        appid = self.get_argument("appid")
        appinfo = self.storage.get_app_info(appid=appid)
        if not appinfo:
            self.send_response(err_code=3201)
            raise tornado.gen.Return()

        openid = self.get_argument("openid", "")
        if openid:
            res = yield wxclient.update_user_info(appid, openid)
            if res["err_code"] == 0:
                self.send_response(data=res["data"])
                raise tornado.gen.Return()

        code = self.get_argument("code", "")
        if code:
            req_data1 = {"code": code, "appid": appid, "secret": appinfo["secret"], "grant_type": "authorization_code"}
            try:
                resp1 = yield httputils.get_dict(url=url.wechat_oauth_access_token, data=req_data1)
            except tornado.httpclient.HTTPError:
                self.send_response(err_code=1001)
                raise tornado.gen.Return()

            resp_data1 = self.parse_oauth_resp(resp1)
            if resp_data1:
                openid = resp_data1["openid"]
                res = {"openid": openid, "appid": appid}
                # Get user info from wechat
                if "snsapi_userinfo" in [v.strip() for v in resp_data1["scope"].split(",")]:
                    req_data2 = {"access_token": resp_data1["access_token"], "openid": openid, "lang": "zh_CN"}
                    try:
                        resp2 = yield httputils.get_dict(url=url.wechat_oauth_userinfo, data=req_data2)
                    except tornado.httpclient.HTTPError:
                        self.send_response(err_code=1001)
                        raise tornado.gen.Return()
                    resp_data2 = self.parse_oauth_resp(resp2)
                    if resp_data2:
                        res.update(resp_data2)
                post_resp_data = dtools.transfer(res, copys=user_attrs, allow_empty=False)
                self.send_response(post_resp_data)
                self.storage.add_user_info(post_resp_data)
                raise tornado.gen.Return()
        self.send_response(err_code=1)
Ejemplo n.º 8
0
    def get(self, siteid, out_trade_no):
        appid = self.get_argument('appid')
        appinfo = self.storage.get_app_info(appid=appid)
        if not appinfo:
            self.send_response(err_code=3201)
            raise tornado.gen.Return()

        req_data = {
            'appid': appid,
            'mch_id': appinfo.get('mch_id'),
            'transaction_id': '',
            'out_trade_no': out_trade_no
        }
        req_key = appinfo['apikey']
        security.add_sign(req_data, req_key)

        try:
            resp = yield httputils.post_dict(url=url.mch_order_query, data=req_data, data_type='xml')
        except tornado.httpclient.HTTPError:
            self.send_response(err_code=1001)
            raise tornado.gen.Return()

        resp_data = self.parse_payment_resp(resp, req_key)
        if resp_data:
            post_resp_data = dtools.transfer(
                resp_data,
                copys=[
                    'appid',
                    'openid',
                    'trade_state',
                    'out_trade_no',
                    'total_fee',
                    'transaction_id',
                    'time_end'
                ]
            )
            self.send_response(post_resp_data)
Ejemplo n.º 9
0
    def post(self):
        post_args = dtools.xml2dict(self.request.body.decode('utf8'))
        logging.info(post_args)
        appinfo = self.storage.get_app_info(openid=post_args['ToUserName'])
        appid = appinfo['appid']
        crypter = None
        if appinfo['is_encrypted']:
            crypter = Prpcrypt(appinfo['encoding_key'])
            plain_xml = crypter.decrypt(post_args['Encrypt'], appid)
            if plain_xml:
                post_args = dtools.xml2dict(plain_xml)
            else:
                # TODO: error
                pass
        req_data = dtools.transfer(
            post_args,
            renames=[
                ('FromUserName', 'openid'),
                ('MsgType', 'msg_type'),
                ('MsgId', 'msg_id'),
                ('CreateTime', 'msg_time'),
                ('Content', 'content'),
                ('Event', 'event_type'),
                ('PicUrl', 'pic_url'),
                ('Location_X', 'latitude'),
                ('Location_Y', 'longitude'),
                ('Label', 'label'),
                ('MediaId', 'media_id')],
            allow_empty=False
        )
        logging.info('message from tencent: %s', req_data)
        req_data['appid'] = appid
        site_info = self.storage.get_site_info(appinfo['siteid'])
        security.add_sign(req_data, site_info['sitekey'])
        try:
            resp = yield httputils.post_dict(
                url=site_info['msg_notify_url'],
                data=req_data)
        except tornado.httpclient.HTTPError:
            self.send_response(err_code=9002)
            raise tornado.gen.Return()
        if resp.code != 200:
            self.send_response(err_code=9002)
            raise tornado.gen.Return()

        try:
            resp_data = json.loads(resp.body.decode('utf8'))
            if resp_data.get('err_code') == 0:
                wx_resp = build_response(from_id=post_args['ToUserName'],
                                         to_id=post_args['FromUserName'],
                                         data=resp_data.get('data'))
                if appinfo['is_encrypted']:
                    wx_resp = encrypt_data(wx_resp, crypter, appid)
                self.send_response(wx_resp)
            else:
                self.send_response(err_code=9003)
        except ValueError:
            self.send_response(err_code=9101)

        # Add basic user info
        openid = req_data['openid']
        user_info = self.storage.get_user_info(appid=appid, openid=openid)
        if not user_info:
            if appinfo['is_verified']:
                yield wxclient.update_user_info(appid, openid)
            else:
                self.storage.add_user_info({
                    'appid': appid,
                    'openid': openid,
                    'fakeid': openid
                })

        # Use mock_browser to get user info
        if not appinfo['is_protected'] and (not user_info or not user_info.get('nickname')) and not req_data.get(
                'event_type'):
            user_resp = yield wxclient.mock_browser.find_user(
                appid=appid,
                timestamp=int(req_data['msg_time']),
                mtype=req_data['msg_type'],
                content=req_data.get('content', '')
            )
            if user_resp['err_code'] == 0:
                more_info = {
                    'appid': appid,
                    'openid': openid,
                    'fakeid': user_resp['data']['fakeid'],
                    'nickname': user_resp['data']['nick_name']
                }
                if not appinfo['is_verified']:
                    contact_resp = yield wxclient.mock_browser.get_contact_info(
                        appid=appid,
                        fakeid=user_resp['data']['fakeid'],
                        msg_id=user_resp['data']['id']
                    )
                    contact_info = contact_resp['data']['contact_info']
                    more_info.update({
                        'sex': contact_info['gender'],
                        'city': contact_info['city'],
                        'province': contact_info['province'],
                        'country': contact_info['country']
                    })
                logging.info('userinfo updated: %s', more_info)
                self.storage.add_user_info(more_info)
Ejemplo n.º 10
0
    def post(self, siteid):
        parse_args = self.assign_arguments(
            essential=['appid',
                       'title',
                       'out_trade_no',
                       'total_fee',
                       'spbill_create_ip',
                       'trade_type'],
            extra=[('detail', ''),
                   ('unionid', ''),
                   ('openid', '')]
        )
        if not parse_args.get('unionid') and not parse_args.get('openid'):
            raise tornado.web.HTTPError(400)

        req_data = dtools.transfer(
            parse_args,
            copys=['appid',
                   'out_trade_no',
                   'detail',
                   'total_fee',
                   'spbill_create_ip',
                   'trade_type',
                   'openid'],
            renames=[('title', 'body')]
        )
        if not req_data.get('openid'):
            req_data['openid'] = self.storage.get_user_info(appid=parse_args['appid'],
                                                            unionid=parse_args['unionid'],
                                                            select_key='openid')
        appinfo = self.storage.get_app_info(appid=req_data['appid'])
        if not appinfo:
            self.send_response(err_code=3201)
            raise tornado.gen.Return()

        req_data.update(
            {
                'attach': 'siteid=' + siteid,
                'mch_id': appinfo.get('mch_id'),
                'notify_url': self.storage.get_site_info(siteid, select_key='pay_notify_url')
            }
        )
        req_key = appinfo['apikey']
        security.add_sign(req_data, req_key)

        try:
            resp = yield httputils.post_dict(url=url.mch_order_add, data=req_data, data_type='xml')
        except tornado.httpclient.HTTPError:
            self.send_response(err_code=1001)
            raise tornado.gen.Return()

        resp_data = self.parse_payment_resp(resp, req_key)
        if resp_data:
            real_sign_data = {
                'appId': resp_data['appid'],
                'timeStamp': str(int(time.time())),
                'nonceStr': security.nonce_str(),
                'package': 'prepay_id=' + resp_data['prepay_id'],
                'signType': 'MD5'
            }
            post_resp_data = {
                'appid': real_sign_data['appId'],
                'timestamp': real_sign_data['timeStamp'],
                'noncestr': real_sign_data['nonceStr'],
                'prepay_id': resp_data['prepay_id'],
                'sign_type': real_sign_data['signType'],
                'pay_sign': security.build_sign(real_sign_data, req_key)
            }
            self.send_response(post_resp_data)
Ejemplo n.º 11
0
    def post(self, siteid):
        parse_args = self.assign_arguments(essential=[
            'appid', 'title', 'out_trade_no', 'total_fee', 'spbill_create_ip',
            'trade_type'
        ],
                                           extra=[('detail', ''),
                                                  ('unionid', ''),
                                                  ('openid', '')])
        if not parse_args.get('unionid') and not parse_args.get('openid'):
            raise tornado.web.HTTPError(400)

        req_data = dtools.transfer(parse_args,
                                   copys=[
                                       'appid', 'out_trade_no', 'detail',
                                       'total_fee', 'spbill_create_ip',
                                       'trade_type', 'openid'
                                   ],
                                   renames=[('title', 'body')])
        if not req_data.get('openid'):
            req_data['openid'] = self.storage.get_user_info(
                appid=parse_args['appid'],
                unionid=parse_args['unionid'],
                select_key='openid')
        appinfo = self.storage.get_app_info(appid=req_data['appid'])
        if not appinfo:
            self.send_response(err_code=3201)
            raise tornado.gen.Return()

        req_data.update({
            'attach':
            'siteid=' + siteid,
            'mch_id':
            appinfo.get('mch_id'),
            'notify_url':
            self.storage.get_site_info(siteid, select_key='pay_notify_url')
        })
        req_key = appinfo['apikey']
        security.add_sign(req_data, req_key)

        try:
            resp = yield httputils.post_dict(url=url.mch_order_add,
                                             data=req_data,
                                             data_type='xml')
        except tornado.httpclient.HTTPError:
            self.send_response(err_code=1001)
            raise tornado.gen.Return()

        resp_data = self.parse_payment_resp(resp, req_key)
        if resp_data:
            real_sign_data = {
                'appId': resp_data['appid'],
                'timeStamp': str(int(time.time())),
                'nonceStr': security.nonce_str(),
                'package': 'prepay_id=' + resp_data['prepay_id'],
                'signType': 'MD5'
            }
            post_resp_data = {
                'appid': real_sign_data['appId'],
                'timestamp': real_sign_data['timeStamp'],
                'noncestr': real_sign_data['nonceStr'],
                'prepay_id': resp_data['prepay_id'],
                'sign_type': real_sign_data['signType'],
                'pay_sign': security.build_sign(real_sign_data, req_key)
            }
            self.send_response(post_resp_data)
Ejemplo n.º 12
0
    def post(self, siteid):
        appid = self.get_argument('appid')
        appinfo = self.storage.get_app_info(appid=appid)
        if not appinfo:
            self.send_response(err_code=3201)
            raise tornado.gen.Return()

        openid = self.get_argument('openid', '')
        if openid:
            res = yield wxclient.update_user_info(appid, openid)
            if res['err_code'] == 0:
                self.send_response(data=res['data'])
                raise tornado.gen.Return()

        code = self.get_argument('code', '')
        if code:
            req_data1 = {
                'code': code,
                'appid': appid,
                'secret': appinfo['secret'],
                'grant_type': 'authorization_code',
            }
            try:
                resp1 = yield httputils.get_dict(
                    url=url.wechat_oauth_access_token, data=req_data1)
            except tornado.httpclient.HTTPError:
                self.send_response(err_code=1001)
                raise tornado.gen.Return()

            resp_data1 = self.parse_oauth_resp(resp1)
            if resp_data1:
                openid = resp_data1['openid']
                res = {
                    'openid': openid,
                    'appid': appid,
                }
                # Get user info from wechat
                if 'snsapi_userinfo' in [
                        v.strip() for v in resp_data1['scope'].split(',')
                ]:
                    req_data2 = {
                        'access_token': resp_data1['access_token'],
                        'openid': openid,
                        'lang': 'zh_CN'
                    }
                    try:
                        resp2 = yield httputils.get_dict(
                            url=url.wechat_oauth_userinfo, data=req_data2)
                    except tornado.httpclient.HTTPError:
                        self.send_response(err_code=1001)
                        raise tornado.gen.Return()
                    resp_data2 = self.parse_oauth_resp(resp2)
                    if resp_data2:
                        res.update(resp_data2)
                post_resp_data = dtools.transfer(res,
                                                 copys=user_attrs,
                                                 allow_empty=False)
                self.send_response(post_resp_data)
                self.storage.add_user_info(post_resp_data)
                raise tornado.gen.Return()
        self.send_response(err_code=1)
Ejemplo n.º 13
0
 def get(self, siteid, uid):
     # Search user info from db
     user_info = self.storage.get_user_info(uid)
     get_resp_data = dtools.transfer(user_info, copys=user_attrs)
     self.send_response(get_resp_data)
Ejemplo n.º 14
0
 def get(self, siteid, uid):
     # Search user info from db
     user_info = self.storage.get_user_info(uid)
     get_resp_data = dtools.transfer(user_info, copys=user_attrs)
     self.send_response(get_resp_data)