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 elasticapm.capture_span('get_result'): try: rpc_result = Auth.get_result(str(request.args.get("request"))) except Exception as e: return handle_exception_with_error_page(e) 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 = APIServer.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"): return jsonify({"message": rpc_result["message"]}) else: return jsonify({"message": "NEXT_TIME"})
def _session_save_student_to_register_(student_id: str): # 将需要注册的用户并保存到 SESSION_STUDENT_TO_REGISTER with elasticapm.capture_span('rpc_get_student'): try: student = APIServer.get_student(student_id) except Exception as e: return handle_exception_with_error_page(e) session[SESSION_STUDENT_TO_REGISTER] = StudentSession(sid_orig=student.student_id, sid=student.student_id_encoded, name=student.name)
def main(): """用户主页""" try: student = APIServer.get_student(session[SESSION_CURRENT_USER].sid_orig) except Exception as e: return handle_exception_with_error_page(e) return render_template('user/main.html', name=session[SESSION_CURRENT_USER].name, student_id_encoded=session[SESSION_CURRENT_USER].sid, last_semester=student.semesters[-1] if student.semesters else None, privacy_level=PrivacySettings.get_level(session[SESSION_CURRENT_USER].sid_orig))
def edit_review(cotc_id: int): """进行评价""" cotc_id = int(cotc_id) cotc = COTeachingClass.get_doc(cotc_id) if not cotc: return render_template('common/error.html', message=MSG_404) if not is_taking(cotc): return render_template('common/error.html', message=MSG_NOT_IN_COURSE) if request.method == 'GET': # 展示表单页面 doc = CourseReview.get_my_review(cotc_id=cotc_id, student_id=session[SESSION_CURRENT_USER].sid_orig) # 已经评分 if doc: my_rating = doc["rate"] my_review = doc["review"] else: my_rating = 0 my_review = "" return render_template("course_review/add_review.html", cotc=cotc, my_rating=my_rating, my_review=my_review) else: # 表单提交 if not request.form.get("rate", None) or request.form["rate"] not in map(str, (1, 2, 3, 4, 5)): flash("请填写正确的评分") return redirect(url_for("course_review.edit_review", cotc_id=cotc_id)) if not request.form.get("review", None): flash("请填写评价") return redirect(url_for("course_review.edit_review", cotc_id=cotc_id)) if len(request.form["review"]) > 200: flash("评论不要超过200个字符") return redirect(url_for("course_review.edit_review", cotc_id=cotc_id)) try: student = APIServer.get_student(session[SESSION_CURRENT_USER].sid_orig) except Exception as e: return handle_exception_with_error_page(e) fuzzy_name = student.klass + "学生" CourseReview.edit_my_review(cotc_id, session[SESSION_CURRENT_USER].sid_orig, int(request.form["rate"]), escape(request.form["review"]), fuzzy_name) flash("评分成功。") return redirect(url_for("course_review.show_review", cotc_id=cotc_id))
def is_taking(cotc: Dict) -> bool: """检查当前用户是否选了这门课""" user_is_taking = False if session.get(SESSION_CURRENT_USER, None): # 检查当前用户是否选了这门课 student = APIServer.get_student(session[SESSION_CURRENT_USER].sid_orig) for semester in sorted(student.semesters, reverse=True): # 新学期可能性大,学期从新到旧查找 timetable = APIServer.get_student_timetable(session[SESSION_CURRENT_USER].sid_orig, semester) for card in timetable.cards: if card.course_id == cotc["course_id"] and cotc["teacher_id_str"] == teacher_list_to_tid_str( card.teachers): user_is_taking = True break if user_is_taking: break return user_is_taking
def login(): """ 登录页 判断学生是否未注册,若已经注册,渲染登录页。否则跳转到注册页面。 """ if request.method == 'GET': if session.get(SESSION_LAST_VIEWED_STUDENT, None): user_name = session[SESSION_LAST_VIEWED_STUDENT].name else: user_name = None return render_template('user/login.html', name=user_name) else: # 表单提交 if not request.form.get("password", None): flash(MSG_EMPTY_PASSWORD) return redirect(url_for("user.login")) # captcha if not TencentCaptcha.verify(): flash(MSG_INVALID_CAPTCHA) return redirect(url_for("user.login")) if request.form.get("xh", None): # 已手动填写用户名 student_id = request.form["xh"] # 检查学号是否存在 try: _ = APIServer.get_student(student_id) except RpcResourceNotFound: flash(MSG_USERNAME_NOT_EXIST) return redirect(url_for("user.login")) except Exception as e: return handle_exception_with_error_page(e) else: if session.get(SESSION_LAST_VIEWED_STUDENT, None): student_id = session[ SESSION_LAST_VIEWED_STUDENT].sid_orig # 没有手动填写,使用获取最后浏览的学生 else: flash(MSG_EMPTY_USERNAME) # 没有最后浏览的学生,必须填写用户名 return redirect(url_for("user.login")) try: success = User.check_password(student_id, request.form["password"]) except ValueError: # 未注册 flash(MSG_NOT_REGISTERED) _session_save_student_to_register_(student_id) return redirect(url_for("user.register")) if success: try: student = APIServer.get_student(student_id) except Exception as e: return handle_exception_with_error_page(e) # 登录态写入 session session[SESSION_CURRENT_USER] = StudentSession( sid_orig=student_id, sid=student.student_id_encoded, name=student.name) return redirect(url_for("user.main")) else: flash(MSG_WRONG_PASSWORD) return redirect(url_for("user.login"))
def email_verification(): """注册:邮箱验证""" if request.method == 'POST': # 设置密码表单提交 if not session.get(SESSION_EMAIL_VER_REQ_ID, None): return render_template("common/error.html", message=MSG_400) req = IdentityVerification.get_request_by_id( session[SESSION_EMAIL_VER_REQ_ID]) if not req: return render_template("common/error.html", message=MSG_TOKEN_INVALID) # 此处不是一定需要验证状态,但是为了保险还是判断一下 if req["status"] != ID_STATUS_TKN_PASSED: return render_template("common/error.html", message=MSG_TOKEN_INVALID) if any( map(lambda x: not request.form.get(x, None), ("password", "password2"))): # check if empty password flash(MSG_EMPTY_PASSWORD) return redirect(url_for("user.email_verification")) if request.form["password"] != request.form["password2"]: flash(MSG_PWD_DIFFERENT) return redirect(url_for("user.email_verification")) sid_orig = req['sid_orig'] # 密码强度检查 pwd_strength_report = zxcvbn(password=request.form["password"]) if pwd_strength_report['score'] < 2: SimplePassword.new(password=request.form["password"], sid_orig=sid_orig) flash(MSG_WEAK_PASSWORD) return redirect(url_for("user.email_verification")) User.add_user(sid_orig=sid_orig, password=request.form['password']) del session[SESSION_EMAIL_VER_REQ_ID] IdentityVerification.set_request_status(str(req["request_id"]), ID_STATUS_PASSWORD_SET) flash(MSG_REGISTER_SUCCESS) # 查询 api-server 获得学生基本信息 try: student = APIServer.get_student(sid_orig) except Exception as e: return handle_exception_with_error_page(e) # 登录态写入 session session[SESSION_CURRENT_USER] = StudentSession( sid_orig=student.student_id, sid=student.student_id_encoded, name=student.name) return redirect(url_for("user.main")) else: # 设置密码页面 if not session.get(SESSION_EMAIL_VER_REQ_ID, None): if not request.args.get("token", None): return render_template("common/error.html", message=MSG_400) with elasticapm.capture_span('verify_email_token'): try: rpc_result = Auth.verify_email_token( token=request.args.get("token", None)) except Exception as e: return handle_exception_with_error_page(e) if rpc_result['success']: session[SESSION_EMAIL_VER_REQ_ID] = rpc_result['request_id'] IdentityVerification.set_request_status( rpc_result['request_id'], ID_STATUS_TKN_PASSED) return render_template('user/emailVerificationProceed.html') else: return render_template("common/error.html", message=MSG_TOKEN_INVALID) else: # have session return render_template('user/emailVerificationProceed.html')