Esempio n. 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 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"})
Esempio n. 2
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 = Entity.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))
Esempio n. 3
0
def _session_save_student_to_register_(student_id: str):
    # 将需要注册的用户并保存到 SESSION_STUDENT_TO_REGISTER
    with tracer.trace('rpc_get_student'):
        try:
            student = Entity.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)
Esempio n. 4
0
def main():
    """用户主页"""
    try:
        student = Entity.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))
Esempio n. 5
0
def is_taking(cotc: Dict) -> bool:
    """检查当前用户是否选了这门课"""
    user_is_taking = False

    if session.get(SESSION_CURRENT_USER, None):
        # 检查当前用户是否选了这门课
        student = Entity.get_student(session[SESSION_CURRENT_USER].sid_orig)
        for semester in sorted(student.semesters,
                               reverse=True):  # 新学期可能性大,学期从新到旧查找
            timetable = Entity.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
Esempio n. 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_old():
            flash(MSG_INVALID_CAPTCHA)
            return redirect(url_for("user.login"))

        if request.form.get("xh", None):  # 已手动填写用户名
            student_id = request.form["xh"]

            # 检查学号是否存在
            try:
                Entity.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 = Entity.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"))
Esempio n. 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"))

        try:
            User.add_user(sid_orig=sid_orig, password=request.form['password'])
        except ValueError:
            flash(MSG_ALREADY_REGISTERED)
            logger.info(
                f"User {sid_orig} try to register again by email token. Filtered when posting."
            )
            return redirect(url_for("user.email_verification"))
        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 = Entity.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 tracer.trace('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)

                req = IdentityVerification.get_request_by_id(
                    rpc_result.request_id)
                student_id = req["sid_orig"]
                if User.exist(student_id):
                    flash(MSG_ALREADY_REGISTERED)
                    logger.info(
                        f"User {student_id} try to register again by email token. Request filtered."
                    )
                    return redirect(url_for("main.main"))

                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')
Esempio n. 8
0
def get_student(student_id: str):
    return Entity.get_student(student_id)