def login(session, username, password, http_header, use_webvpn=False): """ use cookie: just requires "SAAS_U" emulate OAuth login: POST https://ids.xmu.edu.cn/authserver/login?service=https://xmuxg.xmu.edu.cn/login/cas/xmu form data: username, password, lt, dllt, execution, _eventId="submit", rmShown=1 """ # workaround for the AES encryption added in 2020/12/27 with open("./encrypt.js", "r") as file: cryptjs = file.read() ctx = execjs.compile(cryptjs) try: oauth_login_url = get_wrapped_url( "https://ids.xmu.edu.cn/authserver/login?service=https://xmuxg.xmu.edu.cn/login/cas/xmu", use_webvpn) resp = session.get(oauth_login_url, headers=http_header) soup = BeautifulSoup(resp.text, 'lxml') lt = soup.select('input[name="lt"]')[0]["value"] dllt = soup.select('input[name="dllt"]')[0]['value'] execution = soup.select('input[name="execution"]')[0]['value'] salt = soup.select('input#pwdDefaultEncryptSalt')[0]['value'] login_data = { "username": username, "password": ctx.call("encryptAES", password, salt), "lt": lt, "dllt": dllt, "execution": execution, "_eventId": "submit", "rmShown": 1 } session.post( oauth_login_url, login_data, headers=http_header, allow_redirects=True) # will redirect to https://xmuxg.xmu.edu.cn except KeyError: print( json.dumps( { "status": "failed", "reason": "Login failed (server error)" }, indent=4)) sys.exit(1)
def check_recent(username, password, use_webvpn=False, vpn_username=None, vpn_password=None): # create session session = requests.Session() # if use_webvpn: # session = with_webvpn(session, http_header, vpn_username, vpn_password) # bypass captcha # bypass_captcha(session, vpn_username, vpn_password) # login login(session, username, password, http_header, use_webvpn) # get record business id try: get_business_url = get_wrapped_url( 'https://xmuxg.xmu.edu.cn/api/app/221/business/now', use_webvpn) resp = session.get(get_business_url, headers=http_header).text business_id = json.loads(resp)['data'][0]['business']['id'] except KeyError: return ({ "status": "failed", "reason": "auth failed (incorrect auth info or server is down)" }, 1) # get recent checkin status recent_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/api/formEngine/business/%s/myFormInstance" % str(business_id), use_webvpn) resp = session.get(recent_url, headers=http_header).text res_json = json.loads(resp) form_data = res_json['data']['formData'] owner = res_json['data']['owner']['name'] # get recent result record_data = [] for item in form_data: if "打卡详细情况" in item['title']: record_data = item['value']['tableValue'] break record_set = [] for item in record_data: raw = item['rowData'] record = { "date": None, "heat": None, "promise": None, "syndrome": None } for v in raw: if "日期" in v['title']: record['date'] = v['value']['stringValue'] elif "体温" in v['title']: record['heat'] = v['value']['stringValue'] elif '本人承诺' in v['title']: record['promise'] = v['value']['stringValue'] elif '症状' in v['title']: record['syndrome'] = v['value']['stringValue'] record_set.append(record) # get today's modification log # get form id now_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/api/app/214/business/now", use_webvpn) resp = session.get(now_url).text form_id = str(json.loads(resp)['data'][0]['business']['id']) form_begin = json.loads(resp)['data'][0]['business']['name'] cur_time = time.strftime("%Y-%m-%d", time.localtime()) form_instance_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/api/formEngine/business/%s/myFormInstance" % form_id, use_webvpn) resp = session.get(form_instance_url, headers=http_header).text form_json = json.loads(resp)["data"] instance_id = form_json["id"] changelog_url = get_wrapped_url("https://xmuxg.xmu.edu.cn/api/formEngine/formInstances/%s/changeLogs?playerId=owner&businessId=%s" \ % (instance_id, form_id), use_webvpn) log_text = session.get(changelog_url).text log_json = json.loads(log_text)['data']['logs'] status_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/schoolcustom/qrCode", use_webvpn) status_text = session.get(status_url).text status_json = json.loads(status_text)['data'] result = { "owner": owner, "today": len(log_json) > 0 and cur_time == form_begin, "days": status_json["clockDay"], "color": status_json["color"], "payload": record_set } return (result, 0)
def health_report(username, password, use_webvpn=False, vpn_username=None, vpn_password=None): # create session session = requests.Session() if use_webvpn: session = with_webvpn(session, http_header, vpn_username, vpn_password) # login login(session, username, password, http_header, use_webvpn=use_webvpn) # get form id now_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/api/app/214/business/now", use_webvpn) resp = None form_id = None try: resp = session.get(now_url).text form_id = str(json.loads(resp)['data'][0]['business']['id']) except Exception: return ({ "status": "failed", "reason": "Login failed (incorrect auth info or captcha required)" }, 1) # get form instance form_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/api/formEngine/business/%s/formRenderData?playerId=owner" % form_id, use_webvpn) form_components = None try: resp = session.get(form_url, headers=http_header).text form_components = json.loads(resp)["data"]["components"] except Exception: return ({ "status": "failed", "reason": "Internal server error (logged in but cannot get form id)" }, 1) # get owner modification form_instance_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/api/formEngine/business/%s/myFormInstance" % form_id, use_webvpn) resp = session.get(form_instance_url, headers=http_header).text form_json = json.loads(resp)["data"] instance_id = form_json["id"] # change form content value_list = {} for (k, v) in enumerate(form_json["formData"]): name = v['name'] hide = v['hide'] title = v['title'] value = {} if "学生本人是否填写" in title: value['stringValue'] = '是' elif "Can you hereby declare that" in title: value['stringValue'] = '是 Yes' elif v['value']['dataType'] == 'STRING': value['stringValue'] = v['value']['stringValue'] elif v['value']['dataType'] == 'ADDRESS_VALUE': value['addressValue'] = v['value']['addressValue'] value_list[name] = {'hide': hide, 'title': title, 'value': value} # prepare post data post_array = [] for item in form_components: name = item['name'] if name in value_list: hide = True if value_list[name]['hide'] else False if 'select' in name and 'stringValue' in value_list[name][ 'value'] and value_list[name]['value']['stringValue'] == "": hide = True post_array.append({ 'name': name, 'title': value_list[name]['title'], 'value': value_list[name]['value'], 'hide': hide }) else: post_array.append({ 'name': name, 'title': item['title'], 'value': {}, 'hide': True if 'label' not in name else False, }) # post change post_modify_url = get_wrapped_url( "https://xmuxg.xmu.edu.cn/api/formEngine/formInstance/" + instance_id, use_webvpn) post_json = {"formData": post_array, "playerId": "owner"} post_json_str = json.dumps(post_json, ensure_ascii=False) http_header['Content-Type'] = 'application/json' http_header['Referer'] = 'https://xmuxg.xmu.edu.cn/app/214' resp = session.post(post_modify_url, headers=http_header, data=post_json_str.encode('utf-8')) return ({ "status": "success", "info": "automatically checked in successfully.", "name": form_json["owner"]["name"] }, 0)