示例#1
0
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"})
示例#2
0
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)
示例#3
0
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))
示例#4
0
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))
示例#5
0
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
示例#6
0
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"))
示例#7
0
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')