def entry(path: str, params: Dict = None, follow_proto=False, proto="http") -> str: if not path.startswith("/"): path = "/" + path if params: if '?' in path: path = path + "&" + to_form_url(params) else: path = path + "?" + to_form_url(params) if follow_proto: return "//%s%s" % (__HOST, path) else: return "%s://%s%s" % (proto, __HOST, path)
def entry(path, params=None): """ 能用的入口 主要用于回调 """ if path[0] != "/": path = "/" + path if params is None: return "http://open.sklxsj.com" + path else: return "http://open.sklxsj.com" + path + "?" + to_form_url(params)
def login_by_fastlane(_req: HttpRequest, cmd: str = "", account: str = ""): """ 通过命令获取会话 fastlane spaceauth -u [email protected] ex. export FASTLANE_SESSION='---\n- !ruby/object:HTTP::Cookie\n name: myacinfo\n value: DAWTKNV2e32a0823580640561dc9dfd382265048c32c2aa5b04485930b2ada1d1c7eba28dee6c6065c749f708f2a429f8f9f2d0f2f7d2ad629652ca5bc3383c0772d51c6ca34a2f7b09141f7b19c358c2b25d0738079ab1e48a06610228a574342c84ef13349ede1a012c25155e265a17989a3b09631dd953954505153fb7ef71aecfe303530cb684c89e8402cb82d8d4d93c3fc3c1209e334f65f71c7ae0cfdf0349ec757abcb104a591f5bea25ac0f1207004c19645b80ed82fb5cd0d3a740224b2f3aef9e91b049bb63a94ae3c76d027411f077069865209d733617a7a84f54cf7e9488e9b4f0a918d29f184f5ec76d95b5f55def61682f70b7f10fc12dc43d6e380213dd1f702a4f3ccab3ad438cd0f6a87c295e028a12ec410aa3fa689210d040377995914d4d3718b90f85ad5452d5db47ef9ae11c6b3216cf8ab61025adc203b0bf072ce832240c384d83f0f4aaf477a3c7313de4c20c5e32c530ff1ad76aebcd8538ac485a9a46941dfa94ee2f3fb40e38666533326562333665333834343461323366383636666563303166613533303330656361323836MVRYV2\n domain: apple.com\n for_domain: true\n path: "/"\n secure: true\n httponly: true\n expires: \n max_age: \n created_at: 2019-03-15 11:55:51.031441000 +08:00\n accessed_at: 2019-03-15 11:55:51.041509000 +08:00\n- !ruby/object:HTTP::Cookie\n name: dqsid\n value: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJzZnp2ZGFldGJPeWpXaTc1LVpTRmNBIn0.IEYqXF-pxIYdIwP2rdNRNhoxdCzJgGxt4olTZa2fXo8\n domain: olympus.itunes.apple.com\n for_domain: false\n path: "/"\n secure: true\n httponly: true\n expires: \n max_age: 1800\n created_at: &1 2019-03-15 11:55:52.798977000 +08:00\n accessed_at: *1\n curl localhost:8000/apple/login_by_fastlane --data $FASTLANE_SESSION """ if not cmd: cmd = _req.body.decode("utf-8") Assert(len(cmd), "命令行不对") cmd = cmd.replace("\\n", "") cookie = dict(re.compile(r"name:\s+(\S+)\s+value:\s+(\S+)").findall(cmd)) if not account: rsp = requests.post( "https://developer.apple.com/services-account/QH65B2/account/getUserProfile", headers={"cookie": to_form_url(cookie, split=';')}) if rsp.status_code != 200: return { "succ": False, "reason": "无效的fastlane export", } data = rsp.json() account = data["userProfile"]["email"] if account: _info = IosAccountInfo.objects.filter( account=account).first() # type:IosAccountInfo if not _info: _info = IosAccountInfo() _info.account = account _info.save() _info.cookie = json_str(cookie) _info.headers = json_str({}) _info.save() Log("通过fastlane登录[%s]" % account) return { "succ": True, "msg": "登录[%s]成功" % account, } else: return { "succ": False, "msg": "请求不具备提取登录信息", }
def _set_cache(url: str, data: Dict, content: str, expire: int): db_session.set("http:cache:%s:%s" % (url, to_form_url(data)), content, ex=expire // 1000)
def __login(self): if self.csrf_ts > now(): return with Block("账号登录"): ret = requests.post( "https://developer.apple.com/services-account/QH65B2/account/getTeams", json={ "includeInMigrationTeams": 1, }, headers={ 'cookie': to_form_url(self.cookie, split=';'), }, timeout=3, verify=False).json() if not self.team_id else {} if ret.get("resultCode") == 0: self.teams = list(map(lambda x: x["teamId"], ret["teams"])) self.info.team_id = self.team_id = self.teams[0] self.info.teams = json_str(self.teams) self.info.save() else: # 重新登录 self.session = requests.session() self.session.headers["User-Agent"] = "Spaceship 2.117.1" rsp = self.session.get( "https://olympus.itunes.apple.com/v1/app/config?hostname=itunesconnect.apple.com" ).json() self.session.headers["X-Apple-Widget-Key"] = rsp[ "authServiceKey"] # self.session.headers["X-Apple-Widget-Key"] = "16452abf721961a1728885bef033f28e" self.session.headers["Accept"] = "application/json" rsp = self.session.post( "https://idmsa.apple.com/appleauth/auth/signin", json={ "accountName": self.account, "password": self.password, "rememberMe": True, }, timeout=3) self.session.headers["x-apple-id-session-id"] = rsp.headers[ "x-apple-id-session-id"] self.session.headers["scnt"] = rsp.headers["scnt"] if rsp.status_code == 409: # 二次验证 # noinspection PyUnusedLocal rsp = self.session.post( "https://idmsa.apple.com/appleauth/auth") # Log("===> https://idmsa.apple.com/appleauth/auth [%s] %s" % (rsp.status_code, rsp.json())) # 切手机验证码 rsp = self.session.put( "https://idmsa.apple.com/appleauth/auth/verify/phone", json={ "phoneNumber": { "id": 1 }, "mode": "sms", }) Assert(rsp.status_code == 200, "[%s]短信发送失败" % self.account) # Log("===> https://idmsa.apple.com/appleauth/auth/verify/phone [%s] %s" % (rsp.status_code, rsp.json())) _wait_code(self.info, self.session, now()) self.cookie.update(self.session.cookies) self.__expire = now() + 3600 * 1000 if not self.team_id: ret = requests.post( "https://developer.apple.com/services-account/QH65B2/account/getTeams", json={ "includeInMigrationTeams": 1, }, headers={ 'cookie': to_form_url(self.cookie, split=';'), }, timeout=3, verify=False).json() if ret["resultCode"] == 0: self.teams = list(map(lambda x: x["teamId"], ret["teams"])) self.info.team_id = self.team_id = self.teams[0] self.info.teams = json_str(self.teams) self.info.save() else: Log("[%s]获取team失败登出了" % self.account) self.__logout() Log("apple账号[%s:%s]登录完成了" % (self.account, self.team_id))
def _cache(url: str, data: Dict): return db_session.get("http:cache:%s:%s" % (url, to_form_url(data)))
def post(self, title: str, url: str, data: Union[Dict, str] = None, is_json=True, log=True, cache: Union[bool, int] = False, csrf=False, json_api=True, method="POST", is_binary=False, ex_headers=None, status=200): if cache is True: expire = 3600 * 1000 else: expire = cache if not self.is_login: self.__login() start = now() rsp_str = "#NODATA#" try: if "teamId=" in url: if "teamId=%s" % self.team_id not in url: url = url.replace("teamId=", "teamId=%s" % self.team_id) if cache: rsp_str = _cache(url, data) or rsp_str headers = { 'cookie': to_form_url({"myacinfo": self.cookie["myacinfo"]}, split=';'), } if csrf: headers.update({ 'csrf': self.csrf, 'csrf_ts': self.csrf_ts, }) if ex_headers: headers.update(ex_headers) if rsp_str == "#NODATA#": if method.upper() == "GET": rsp = requests.get(url, params=data, headers=headers, timeout=3, verify=False) else: rsp = requests.post(url, data=data, headers=headers, timeout=3, verify=False) rsp_str = rsp.text if rsp.headers.get("csrf"): self.csrf = rsp.headers["csrf"] self.csrf_ts = int(rsp.headers["csrf_ts"]) Assert(rsp.status_code == status, "请求[%s]异常[%s]" % (title, rsp.status_code)) if json_api: _data = str_json_i(rsp_str) or {} if _data.get("resultCode") == 1100: self.__logout() raise Fail("登录[%s]过期了[%s][%s]" % (self.account, _data.get("resultString"), _data.get("userString"))) Assert( _data.get("resultCode") == 0, "请求业务[%s]失败[%s][%s]" % (title, _data.get("resultString"), _data.get("userString"))) if log: Log("apple请求[%s][%s]发送[%r]成功[%r]" % (title, now() - start, data, rsp_str)) if is_binary: rsp_str = base64(rsp.content) if cache: _set_cache(url, data, rsp_str, expire=expire) if is_json: return str_json(rsp_str) elif is_binary: return base64decode(rsp_str) else: return rsp_str except Exception as e: if log: Log("apple请求[%s][%s]发送[%r]失败[%r]" % (title, now() - start, data, rsp_str)) raise e