예제 #1
0
def android_client_get_ics(resource_type, identifier, semester):
    """
    android client get a student or teacher's ics file

    If the student does not have privacy mode, anyone can use student number to subscribe his calendar.
    If the privacy mode is on and there is no HTTP basic authentication, return a 401(unauthorized)
    status code and the Android client ask user for password to try again.
    """
    from flask import redirect, url_for, request

    from everyclass.server.db.dao import PrivacySettings, CalendarToken, User
    from everyclass.server.rpc.api_server import APIServer
    from everyclass.server.utils.resource_identifier_encrypt import decrypt

    # 检查 URL 参数
    try:
        res_type, res_id = decrypt(identifier)
    except ValueError:
        return "Invalid identifier", 400
    if resource_type not in ('student',
                             'teacher') or resource_type != res_type:
        return "Unknown resource type", 400

    if resource_type == 'teacher':
        try:
            teacher = APIServer.get_teacher_timetable(res_id, semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

        cal_token = CalendarToken.get_or_set_calendar_token(
            resource_type=resource_type,
            identifier=teacher.teacher_id,
            semester=semester)
        return redirect(
            url_for('calendar.ics_download', calendar_token=cal_token))
    else:  # student
        try:
            student = APIServer.get_student_timetable(res_id, semester)
        except Exception as e:
            return handle_exception_with_error_page(e)

        with elasticapm.capture_span('get_privacy_settings'):
            privacy_level = PrivacySettings.get_level(student.student_id)

        # get authorization from HTTP header and verify password if privacy is on
        if privacy_level != 0:
            if not request.authorization:
                return "Unauthorized (privacy on)", 401
            username, password = request.authorization
            if not User.check_password(username, password):
                return "Unauthorized (password wrong)", 401
            if student.student_id != username:
                return "Unauthorized (username mismatch)", 401

        cal_token = CalendarToken.get_or_set_calendar_token(
            resource_type=resource_type,
            identifier=student.student_id,
            semester=semester)
        return redirect(
            url_for('calendar.ics_download', calendar_token=cal_token))
예제 #2
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"))