def register_by_password_status_refresh( request_id: str) -> Tuple[bool, str, Optional[str]]: """通过教务密码注册-刷新状态,返回是否成功、auth message及学号/教工号(如果成功)""" req = VerificationRequest.find_by_id(uuid.UUID(request_id)) if not req: raise IdentityVerifyRequestNotFoundError if req.method != "password": logger.warn( "Non-password verification request is trying get status from password interface" ) raise IdentityVerifyMethodNotExpectedError if req.method == VerificationRequest.STATUS_PWD_SUCCESS: raise RequestIDUsed( "Request ID is used and password is set. It cannot be reused.") # fetch status from everyclass-auth with tracer.trace('get_result'): rpc_result = Auth.get_result(str(request_id)) if rpc_result.success: # 密码验证通过,设置请求状态并新增用户 verification_req = VerificationRequest.find_by_id( uuid.UUID(request_id)) verification_req.set_status_success() add_user(identifier=verification_req.identifier, password=verification_req.extra["password"], password_encrypted=True) return True, "SUCCESS", verification_req.identifier else: # 如果不是成功状态则返回auth服务返回的message return False, rpc_result.message, None
def register_by_password_status(): if not request.args.get("request", None) or not isinstance(request.args["request"], str): return "Invalid request" req = IdentityVerificationDAO.get_request_by_id(request.args.get("request")) if not req: return "Invalid request" if req["verification_method"] != "password": logger.warn("Non-password verification request is trying get status from password interface") return "Invalid request" # fetch status from everyclass-auth with elasticapm.capture_span('rpc_get_auth_state'): rpc_result = HttpRpc.call_with_error_page('{}/get_result'.format(app.config['AUTH_BASE_URL']), data={'request_id': str(request.args.get("request"))}, retry=True) if isinstance(rpc_result, str): return rpc_result api_response = rpc_result if api_response['success']: IdentityVerificationDAO.set_request_status(str(request.args.get("request")), ID_STATUS_PWD_SUCCESS) return jsonify({"message": "SUCCESS"}) elif api_response["message"] in ("PASSWORD_WRONG", "INTERNAL_ERROR"): return jsonify({"message": api_response["message"]}) else: return jsonify({"message": "next-time"})
def register_by_password_status(): """AJAX 刷新教务验证状态""" if not request.args.get("request", None) or not isinstance( request.args["request"], str): return "Invalid request" req = IdentityVerification.get_request_by_id(request.args.get("request")) if not req: return "Invalid request" if req["verification_method"] != "password": logger.warn( "Non-password verification request is trying get status from password interface" ) return "Invalid request" # fetch status from everyclass-auth with tracer.trace('get_result'): try: rpc_result = Auth.get_result(str(request.args.get("request"))) except Exception as e: return handle_exception_with_error_page(e) logger.info(f"RPC result: {rpc_result}") if rpc_result.success: # 密码验证通过,设置请求状态并新增用户 IdentityVerification.set_request_status( str(request.args.get("request")), ID_STATUS_PWD_SUCCESS) verification_req = IdentityVerification.get_request_by_id( str(request.args.get("request"))) # 从 api-server 查询学生基本信息 try: student = Entity.get_student(verification_req["sid_orig"]) except Exception as e: return handle_exception_with_error_page(e) # 添加用户 try: User.add_user(sid_orig=verification_req["sid_orig"], password=verification_req["password"], password_encrypted=True) except ValueError: pass # 已经注册成功,但不知为何进入了中间状态,没有执行下面的删除 session 的代码,并且用户刷新页面 # write login state to session flash(MSG_REGISTER_SUCCESS) if SESSION_PWD_VER_REQ_ID in session: del session[SESSION_PWD_VER_REQ_ID] session[SESSION_CURRENT_USER] = StudentSession( sid_orig=student.student_id, sid=student.student_id_encoded, name=student.name) return jsonify({"message": "SUCCESS"}) elif rpc_result.message in ("PASSWORD_WRONG", "INTERNAL_ERROR", "INVALID_REQUEST_ID"): return jsonify({"message": rpc_result.message}) else: return jsonify({"message": "NEXT_TIME"})
def js_set_preference(): """AJAX更新偏好设置""" if request.form.get("privacyLevel", None): # update privacy level privacy_level = int(request.form["privacyLevel"]) if privacy_level not in (0, 1, 2): logger.warn("Received malformed set preference request. privacyLevel value not valid.") return jsonify({"acknowledged": False, "message" : "Invalid value"}) PrivacySettingsDAO.set_level(session[SESSION_CURRENT_USER].sid_orig, privacy_level) return jsonify({"acknowledged": True})
def ensure_slots(cls, dct: Dict): """移除 dataclass 中不存在的key,预防 dataclass 的 __init__ 中 unexpected argument 的发生。""" _names = [x.name for x in fields(cls)] _del = [] for key in dct: if key not in _names: _del.append(key) for key in _del: del dct[key] # delete unexpected keys logger.warn( "Unexpected field `{}` is removed when converting dict to dataclass `{}`" .format(key, cls.__name__)) return dct
def get_username_from_jwt(token: str) -> Optional[str]: """从JWT token中解析出用户名,如果解析失败,返回None""" from everyclass.server import logger if not token: logger.warn(f"empty token received, type: {type(token)}") try: payload = decode_jwt_payload(token) except jwt.exceptions.PyJWTError as e: logger.warn( "JWT token decode failed, maybe it was tampered with client side", extra={ "token": token, "error": repr(e) }) return None if 'username' not in payload: logger.warn("aud not in payload. the token is weird.") return None return payload["username"]