|
|
@@ -0,0 +1,254 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+import os
|
|
|
+import re
|
|
|
+import sys
|
|
|
+import time
|
|
|
+import pymysql
|
|
|
+import logging
|
|
|
+import jwt
|
|
|
+import json
|
|
|
+from datetime import datetime
|
|
|
+
|
|
|
+from mitmproxy import flowfilter
|
|
|
+from mitmproxy import http
|
|
|
+from mitmproxy import ctx
|
|
|
+
|
|
|
+sys.path.append('../')
|
|
|
+import utils.Utils as Utils
|
|
|
+sys.path.pop()
|
|
|
+
|
|
|
+"""
|
|
|
+#http.HTTPFlow 实例 flow
|
|
|
+flow.request.http_version #HTTP 版本
|
|
|
+flow.request.headers #获取所有头信息,包含Host、User-Agent、Content-type等字段
|
|
|
+flow.request.cookies #cookie头
|
|
|
+flow.request.url #完整的请求地址,包含域名及请求参数,但是不包含放在body里面的请求参数
|
|
|
+flow.request.pretty_url #同flow.request.url目前没看出什么差别
|
|
|
+flow.request.host #域名
|
|
|
+flow.request.port #请求的目标端口
|
|
|
+flow.request.method #请求方式。POST、GET等
|
|
|
+flow.request.scheme #什么请求 ,如https
|
|
|
+flow.request.path # 请求的路径,url除域名之外的内容
|
|
|
+flow.request.get_text() #请求中body内容,有一些http会把请求参数放在body里面,那么可通过此方法获取,返回字典类型
|
|
|
+flow.request.replace() # 使用正则替换content中的内容
|
|
|
+flow.request.query #返回MultiDictView类型的数据,url直接带的键值参数
|
|
|
+flow.request.get_content()#bytes,结果如flow.request.get_text()
|
|
|
+flow.request.raw_content #bytes,结果如flow.request.get_content()
|
|
|
+flow.request.urlencoded_form #MultiDictView,content-type:application/x-www-form-urlencoded时的请求参数,不包含url直接带的键值参数
|
|
|
+flow.request.multipart_form #MultiDictView,content-type:multipart/form-data
|
|
|
+flow.request.timestamp_start #请求开始的时间戳
|
|
|
+flow.request.timestamp_end #请求结束的时间戳
|
|
|
+
|
|
|
+时的请求参数,不包含url直接带的键值参数
|
|
|
+#以上均为获取request信息的一些常用方法,对于response,同理
|
|
|
+flow.response.status_code #状态码
|
|
|
+flow.response.headers #获取所有头信息
|
|
|
+flow.response.cookies #cookie头
|
|
|
+flow.response.text#返回内容,已解码
|
|
|
+flow.response.content #返回内容,二进制
|
|
|
+flow.response.set_text() #修改返回内容,不需要转码
|
|
|
+flow.response.replace() # 使用正则替换content中的内容
|
|
|
+flow.response.timestamp_start #响应开始的时间戳
|
|
|
+flow.response.timestamp_end #响应结束的时间戳
|
|
|
+
|
|
|
+"""
|
|
|
+
|
|
|
+class OfpayHelper:
|
|
|
+ order_simple_data = {
|
|
|
+ "awardId": "W1155090378949787660",
|
|
|
+ "activityId": "A923605206137307136",
|
|
|
+ "activityName": "采集",
|
|
|
+ "activityState": "2",
|
|
|
+ "activityStartTime": "2024-01-01 00:00",
|
|
|
+ "activityEndTime": "2024-03-31 23:59",
|
|
|
+ "businessType": "4005",
|
|
|
+ "outActivityCode": "eCoffee",
|
|
|
+ "mobile": "",
|
|
|
+ "prizeId": "sku14117",
|
|
|
+ "prizeName": "数据采集成功",
|
|
|
+ "prizeAlias": "",
|
|
|
+ # 假设 'randomCode' 是字符串,你需要给这个变量赋予适当的值
|
|
|
+ "prizeDesc": None,
|
|
|
+ "prizeDescUrl": "https://mstatic.ofpay.com/marketing/upload/ca2ed3a05b2846b7909debf2df8e3495.png",
|
|
|
+ "prizeBannerUrl": "https://mstatic.ofpay.com/marketing/upload/c4d1a0b94b50462eb0f040306a9badf4.png",
|
|
|
+ "categoryId": "1",
|
|
|
+ "rechargeType": "09",
|
|
|
+ "goodsScene": "0",
|
|
|
+ "goodsList": [],
|
|
|
+ "orderNum": 1,
|
|
|
+ "createTime": None,
|
|
|
+ "imgUrl": "https://mstatic.ofpay.com/marketing/upload/7e21faea6ba94379bf16968c246cb044.png",
|
|
|
+ "orderStatus": "3",
|
|
|
+ "detailId": "T123456789",
|
|
|
+ "clientAccount": "13430389115",
|
|
|
+ "redeemCode": "",
|
|
|
+ "redeemCodeStatus": "",
|
|
|
+ "dynamicCodeSign": "1",
|
|
|
+ "startEffectTime": "",
|
|
|
+ "endEffectTime": None,
|
|
|
+ "toExpireFlag": "0",
|
|
|
+ "faceVal": "",
|
|
|
+ "orderId": "T240226090160697",
|
|
|
+ "tenantId": "0000000191",
|
|
|
+ "price": "",
|
|
|
+ "awardPrice": "0.0",
|
|
|
+ "salePrice": "0.0",
|
|
|
+ "rechargeId": "R1211608194317672448",
|
|
|
+ "rechargeTime": "2024-02-26 09:30:00",
|
|
|
+ "payStatus": "2",
|
|
|
+ "discountPrice": "",
|
|
|
+ "activityPrice": "",
|
|
|
+ # JSON 字符串需要解析为 Python 字典
|
|
|
+ "customerInfo": {
|
|
|
+ "device_id": "D29ED082-549A-4882-98FC-8BB881D1552B",
|
|
|
+ "loginType": "interactiveIGoChoose",
|
|
|
+ "gameAccount": "13430389115",
|
|
|
+ "city_code": "440100",
|
|
|
+ "cisno": "ZbHv0CEM2cGjx0DB9DXVJg==",
|
|
|
+ "isNewUser": "0",
|
|
|
+ "marketId": "M923156289016692736",
|
|
|
+ "city_name": "广州市",
|
|
|
+ "phone": "13430389115",
|
|
|
+ "fromEntry": "APP",
|
|
|
+ "currentTimeMillis": "1708910189982",
|
|
|
+ "userUuid": "Pfd6kjTSmjCfQ8boswe1PpAmfgZW0acz",
|
|
|
+ "cust_id": "Pfd6kjTSmjCfQ8boswe1PpAmfgZW0acz",
|
|
|
+ "invitationCode": "BGCKWC"
|
|
|
+ },
|
|
|
+ "callbackOrder": "",
|
|
|
+ "activityRechargeEffectStartTime": "",
|
|
|
+ "activityRechargeEffectEndTime": "",
|
|
|
+ "accountType": "",
|
|
|
+ "payFlag": "1",
|
|
|
+ "activityPayFlag": True,
|
|
|
+ # JSON 字符串需要解析为 Python 字典
|
|
|
+ "thirdInfo": {
|
|
|
+ "faceValue": "30.00",
|
|
|
+ "customGatewayId": "ZDY_ICBC_ZJWN",
|
|
|
+ "showSign": "1",
|
|
|
+ "xcxShowSign": "2",
|
|
|
+ "order": "28",
|
|
|
+ "toBPrice": "30.00",
|
|
|
+ "showPhone": "1",
|
|
|
+ "pointActivity": "HD0460132E7oLMG1mH",
|
|
|
+ "stockShowSign": "2"
|
|
|
+ },
|
|
|
+ "vendorVoucher": "",
|
|
|
+ "productUseMsg": "",
|
|
|
+ "proof": "",
|
|
|
+ "amount": 1,
|
|
|
+ "parentActivityNo": "",
|
|
|
+ "parentDetailId": "",
|
|
|
+ # JSON 字符串需要解析为 Python 字典
|
|
|
+ "subOrderExt": {
|
|
|
+ "orderStatus": "",
|
|
|
+ "payStatus": ""
|
|
|
+ },
|
|
|
+ "logisticsNo": "",
|
|
|
+ "company": "",
|
|
|
+ "promoteId": "",
|
|
|
+ "version": 1,
|
|
|
+ "gateWayId": "",
|
|
|
+ "payType": "",
|
|
|
+ "needRechargeNum": "0"
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ def __init__(self):
|
|
|
+ self.domain = 'market-web.ofpay.com';
|
|
|
+ self.db_conn = None;
|
|
|
+ self.connect_mysql();
|
|
|
+
|
|
|
+ def connect_mysql(self):
|
|
|
+ config = {
|
|
|
+ 'host':'47.106.225.136',
|
|
|
+ 'port':3306,
|
|
|
+ 'user':'root',
|
|
|
+ 'passwd':'sjojo123456',
|
|
|
+ 'database':'mitmproxy',
|
|
|
+ 'charset':'utf8'
|
|
|
+ };
|
|
|
+ db_conn = None;
|
|
|
+ while True:
|
|
|
+ try:
|
|
|
+ db_conn = pymysql.connect(**config);
|
|
|
+ db_conn.ping(reconnect=True);
|
|
|
+ except pymysql.OperationalError as e:
|
|
|
+ print(e);
|
|
|
+ print('连接断开,正在尝试重新连接...');
|
|
|
+ if db_conn:
|
|
|
+ db_conn.close();
|
|
|
+ db_conn = pymysql.connect(**config);
|
|
|
+ time.sleep(1);
|
|
|
+ else:
|
|
|
+ break;
|
|
|
+ self.db_conn = db_conn;
|
|
|
+
|
|
|
+ def request(self, flow: http.HTTPFlow):
|
|
|
+ if flow.request.host != self.domain:
|
|
|
+ return;
|
|
|
+ url = flow.request.url;
|
|
|
+ path = flow.request.path;
|
|
|
+ request = flow.request;
|
|
|
+
|
|
|
+ def response(self, flow: http.HTTPFlow):
|
|
|
+ if flow.request.host != self.domain:
|
|
|
+ return;
|
|
|
+ url = flow.request.url;
|
|
|
+ path = flow.request.path;
|
|
|
+ if path.startswith('/h5/union/api/interactiveIGoChoose/orderList'):
|
|
|
+ self.handle_orderlist(flow);
|
|
|
+
|
|
|
+ def handle_orderlist(self, flow: http.HTTPFlow):
|
|
|
+ ctx.log.info('###handle_orderlist###');
|
|
|
+ request = flow.request;
|
|
|
+ response = flow.response;
|
|
|
+ cookies = dict(request.cookies) # 转换cookies格式为dict
|
|
|
+ if 'unionToken_interactiveIGoChoose' not in cookies:
|
|
|
+ return;
|
|
|
+ account = None;
|
|
|
+ try:
|
|
|
+ payload = jwt.decode(cookies['unionToken_interactiveIGoChoose'], verify=False);
|
|
|
+ info_str = payload.get('customerInfo');
|
|
|
+ if info_str:
|
|
|
+ customer_info = json.loads(info_str);
|
|
|
+ account = customer_info['phone'];
|
|
|
+ except jwt.PyJWTError as e:
|
|
|
+ print('jwt token解析失败');
|
|
|
+ else:
|
|
|
+ pass
|
|
|
+ finally:
|
|
|
+ pass
|
|
|
+ if not account:
|
|
|
+ return;
|
|
|
+ headers = dict(request.headers);
|
|
|
+ uuid = headers['UUID'];
|
|
|
+ authorization = headers['Authorization'];
|
|
|
+ user_agent = headers['User-Agent'];
|
|
|
+ market_id = request.query.get('marketId');
|
|
|
+ event_visitor_id = request.query.get('eventVisitorId');
|
|
|
+
|
|
|
+
|
|
|
+ create_time = '2024-01-01 00:00:00';
|
|
|
+ capture_code = Utils.generate_random_code(6);
|
|
|
+ simple_data = OfpayHelper.order_simple_data;
|
|
|
+ simple_data['prizeDesc'] = capture_code;
|
|
|
+ simple_data['createTime'] = create_time;
|
|
|
+ simple_data['endEffectTime'] = create_time;
|
|
|
+
|
|
|
+ rsp_params = json.loads(response.get_text());
|
|
|
+ if rsp_params['code'] == 'success':
|
|
|
+ rsp_data = rsp_params['data'];
|
|
|
+ rsp_data['list'].insert(0, simple_data);
|
|
|
+
|
|
|
+ response.set_text(json.dump(rsp_params));
|
|
|
+
|
|
|
+ update_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S');
|
|
|
+ sql_query = f'''
|
|
|
+ CALL UpdateElifeAccountData(%s, %s, %s, %s, %s, %s, %s, %, NOW());
|
|
|
+ ''';
|
|
|
+ sql_params = (account, uuid, authorization, str(cookies), user_agent, market_id, event_visitor_id, capture_code , update_time);
|
|
|
+ cursor = self.db_conn.cursor();
|
|
|
+
|
|
|
+ cursor.execute(sql_query, sql_params);
|
|
|
+ cursor.close();
|