コード例 #1
0
ファイル: auth.py プロジェクト: Cal-CS-61A-Staff/ok
def user_from_provider_token(token):
    """
    Get a User with the given access token, or create one if no User with
    this email is found. If the token is invalid, return None.
    """
    if not token:
        return None
    if use_testing_login() and token == "test":
        return user_from_email("*****@*****.**")

    if provider_name == GOOGLE:
        user_data = google_user_data(token)
    elif provider_name == MICROSOFT:
        user_data = microsoft_user_data(token)

    if not user_data or 'email' not in user_data:
        if provider_name == GOOGLE:
            cache.delete_memoized(google_user_data, token)
        elif provider_name == MICROSOFT:
            cache.delete_memoized(microsoft_user_data, token)

        logger.warning("Auth Retry failed for token {} - {}".format(token, user_data))
        return None

    return user_from_email(user_data['email'])
コード例 #2
0
ファイル: models.py プロジェクト: xiaomeow/ok
    def create_staff_tasks(cls,
                           backups,
                           staff,
                           assignment_id,
                           course_id,
                           kind,
                           only_unassigned=False):
        if only_unassigned:
            # Filter out backups that have a GradingTasks
            backups = [
                b for b in backups
                if not cls.query.filter_by(backup_id=b).count()
            ]

        paritions = chunks(list(backups), len(staff))
        tasks = []
        for assigned_backups, grader in zip(paritions, staff):
            for backup_id in assigned_backups:
                task = cls(kind=kind,
                           backup_id=backup_id,
                           course_id=course_id,
                           assignment_id=assignment_id,
                           grader=grader)
                tasks.append(task)
                cache.delete_memoized(User.num_grading_tasks, grader)
        db.session.add_all(tasks)
        return tasks
コード例 #3
0
ファイル: admin.py プロジェクト: gratimax/ok
def templates(cid, aid):
    courses, current_course = get_courses(cid)
    assignment = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none()
    if not Assignment.can(assignment, current_user, 'edit'):
        flash('Insufficient permissions', 'error')
        return abort(401)

    form = forms.AssignmentTemplateForm()

    if assignment.course != current_course:
        return abort(401)

    if form.validate_on_submit():
        files = request.files.getlist("template_files")
        if files:
            templates = {}
            for template in files:
                templates[template.filename] = str(template.read(), 'latin1')
            assignment.files = templates
        cache.delete_memoized(Assignment.name_to_assign_info)
        db.session.commit()
        flash("Templates Uploaded", "success")

    # TODO: Use same student facing code rendering/highlighting
    return render_template('staff/course/assignment.template.html',
                           assignment=assignment, form=form, courses=courses,
                           current_course=current_course)
コード例 #4
0
ファイル: auth.py プロジェクト: nnbaokhang/ok
def user_from_provider_token(token):
    """
    Get a User with the given access token, or create one if no User with
    this email is found. If the token is invalid, return None.
    """
    if not token:
        return None
    if use_testing_login() and token == "test":
        return user_from_email("*****@*****.**")

    if provider_name == GOOGLE:
        user_data = google_user_data(token)
    elif provider_name == MICROSOFT:
        user_data = microsoft_user_data(token)

    if not user_data or 'email' not in user_data:
        if provider_name == GOOGLE:
            cache.delete_memoized(google_user_data, token)
        elif provider_name == MICROSOFT:
            cache.delete_memoized(microsoft_user_data, token)

        logger.warning("Auth Retry failed for token {} - {}".format(
            token, user_data))
        return None

    return user_from_email(user_data['email'])
コード例 #5
0
ファイル: admin.py プロジェクト: shivasheeshyadav/ok
def templates(cid, aid):
    courses, current_course = get_courses(cid)
    assignment = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none()
    if not Assignment.can(assignment, current_user, 'edit'):
        flash('Insufficient permissions', 'error')
        return abort(401)

    form = forms.AssignmentTemplateForm()

    if assignment.course != current_course:
        return abort(401)

    if form.validate_on_submit():
        files = request.files.getlist("template_files")
        if files:
            templates = {}
            for template in files:
                templates[template.filename] = str(template.read(), 'latin1')
            assignment.files = templates
        cache.delete_memoized(Assignment.name_to_assign_info)
        db.session.commit()
        flash("Templates Uploaded", "success")

    # TODO: Use same student facing code rendering/highlighting
    return render_template('staff/course/assignment/assignment.template.html',
                           assignment=assignment, form=form, courses=courses,
                           current_course=current_course)
コード例 #6
0
ファイル: auth.py プロジェクト: shivasheeshyadav/ok
def user_from_google_token(token):
    """
    Get a User with the given Google access token, or create one if no User with
    this email is found. If the token is invalid, return None.
    """
    if not token:
        return None
    if use_testing_login() and token == "test":
        return user_from_email("*****@*****.**")
    user_data = google_user_data(token)

    if user_data is None:
        cache.delete_memoized(google_user_data, token)

    if not user_data:
        return None
    return user_from_email(user_data['email'])
コード例 #7
0
ファイル: admin.py プロジェクト: gratimax/ok
def new_assignment(cid):
    courses, current_course = get_courses(cid)
    if not Assignment.can(None, current_user, 'create'):
        flash('Insufficient permissions', 'error')
        return abort(401)

    form = forms.AssignmentForm(course=current_course)
    if form.validate_on_submit():
        model = Assignment(course_id=cid, creator_id=current_user.id)
        form.populate_obj(model)
        db.session.add(model)
        db.session.commit()
        cache.delete_memoized(Assignment.name_to_assign_info)

        flash("Assignment created successfully.", "success")
        return redirect(url_for(".course_assignments", cid=cid))

    return render_template('staff/course/assignment.new.html', form=form,
                           courses=courses, current_course=current_course)
コード例 #8
0
ファイル: models.py プロジェクト: xiaomeow/ok
    def create(cid, enrollment_info=None, role=STUDENT_ROLE):
        if enrollment_info is None:
            enrollment_info = []
        new_records = []
        for info in enrollment_info:
            usr_id, sid = info['id'], info['sid']
            class_account, section = info['class_account'], info['section']
            record = Enrollment.query.filter_by(user_id=usr_id,
                                                course_id=cid).one_or_none()
            if not record:
                record = Enrollment(course_id=cid, user_id=usr_id)
                new_records.append(record)

            record.role = role
            record.sid = sid
            record.class_account = class_account
            record.section = section

        db.session.add_all(new_records)

        cache.delete_memoized(User.is_enrolled)
コード例 #9
0
ファイル: admin.py プロジェクト: shivasheeshyadav/ok
def new_assignment(cid):
    courses, current_course = get_courses(cid)
    if not Assignment.can(None, current_user, 'create'):
        flash('Insufficient permissions', 'error')
        return abort(401)

    form = forms.AssignmentForm(course=current_course)
    if form.validate_on_submit():
        model = Assignment(course_id=cid, creator_id=current_user.id)
        form.populate_obj(model)
        db.session.add(model)
        db.session.commit()
        cache.delete_memoized(Assignment.name_to_assign_info)

        flash("Assignment created successfully.", "success")
        if form.visible.data:
            return redirect(url_for(".templates", cid=cid, aid=model.id))
        return redirect(url_for(".course_assignments", cid=cid))

    return render_template('staff/course/assignment/assignment.new.html', form=form,
                           courses=courses, current_course=current_course)
コード例 #10
0
ファイル: auth.py プロジェクト: Cal-CS-61A-Staff/ok
def user_from_google_token(token):
    """
    Get a User with the given Google access token, or create one if no User with
    this email is found. If the token is invalid, return None.
    """
    if not token:
        return None
    if use_testing_login() and token == "test":
        return user_from_email("*****@*****.**")
    user_data = google_user_data(token)

    if not user_data or "email" not in user_data:
        cache.delete_memoized(google_user_data, token)
        logger.warning("Could not login with oauth. Trying again - {}".format(user_data))
        user_data = google_user_data(token, timeout=10)

    if not user_data or "email" not in user_data:
        cache.delete_memoized(google_user_data, token)
        logger.warning("Auth Retry failed for token {} - {}".format(token, user_data))
        return None

    return user_from_email(user_data["email"])
コード例 #11
0
ファイル: admin.py プロジェクト: shivasheeshyadav/ok
def client_version(name):
    courses, current_course = get_courses()

    version = Version.query.filter_by(name=name).one_or_none()
    if not version:
        version = Version(name=name)
    form = forms.VersionForm(obj=version)
    if form.validate_on_submit():
        form.populate_obj(version)

        db.session.add(version)
        db.session.commit()

        cache.delete_memoized(Version.get_current_version, name)
        cache.delete_memoized(ok_api.Version.get)

        flash(name + " version updated successfully.", "success")
        return redirect(url_for(".client_version", name=name))

    return render_template('staff/client_version.html',
                           courses=courses, current_course=current_course,
                           version=version, form=form)
コード例 #12
0
ファイル: admin.py プロジェクト: gratimax/ok
def client_version(name):
    courses, current_course = get_courses()

    version = Version.query.filter_by(name=name).one_or_none()
    if not version:
        version = Version(name=name)
    form = forms.VersionForm(obj=version)
    if form.validate_on_submit():
        form.populate_obj(version)

        db.session.add(version)
        db.session.commit()

        cache.delete_memoized(Version.get_current_version, name)
        cache.delete_memoized(ok_api.Version.get)

        flash(name + " version updated successfully.", "success")
        return redirect(url_for(".client_version", name=name))

    return render_template('staff/client_version.html',
                           courses=courses, current_course=current_course,
                           version=version, form=form)
コード例 #13
0
ファイル: admin.py プロジェクト: shivasheeshyadav/ok
def assignment(cid, aid):
    courses, current_course = get_courses(cid)
    assign = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none()
    if not assign:
        return abort(404)
    if not Assignment.can(assign, current_user, 'edit'):
        flash('Insufficient permissions', 'error')
        return abort(401)

    form = forms.AssignmentUpdateForm(obj=assign, course=current_course)
    stats = Assignment.assignment_stats(assign.id)

    if form.validate_on_submit():
        # populate_obj converts back to UTC
        form.populate_obj(assign)
        assign.creator_id = current_user.id
        cache.delete_memoized(Assignment.name_to_assign_info)
        db.session.commit()
        flash("Assignment edited successfully.", "success")

    return render_template('staff/course/assignment/assignment.html', assignment=assign,
                           form=form, courses=courses, stats=stats,
                           current_course=current_course)
コード例 #14
0
ファイル: admin.py プロジェクト: gratimax/ok
def assignment(cid, aid):
    courses, current_course = get_courses(cid)
    assign = Assignment.query.filter_by(id=aid, course_id=cid).one_or_none()
    if not assign:
        return abort(404)
    if not Assignment.can(assign, current_user, 'edit'):
        flash('Insufficient permissions', 'error')
        return abort(401)

    form = forms.AssignmentUpdateForm(obj=assign, course=current_course)
    stats = Assignment.assignment_stats(assign.id)

    if form.validate_on_submit():
        # populate_obj converts back to UTC
        form.populate_obj(assign)
        assign.creator_id = current_user.id
        cache.delete_memoized(Assignment.name_to_assign_info)
        db.session.commit()
        flash("Assignment edited successfully.", "success")

    return render_template('staff/course/assignment.html', assignment=assign,
                           form=form, courses=courses, stats=stats,
                           current_course=current_course)
コード例 #15
0
ファイル: auth.py プロジェクト: xiaomeow/ok
def user_from_google_token(token):
    """
    Get a User with the given Google access token, or create one if no User with
    this email is found. If the token is invalid, return None.
    """
    if not token:
        return None
    if use_testing_login() and token == "test":
        return user_from_email("*****@*****.**")
    user_data = google_user_data(token)

    if not user_data or 'email' not in user_data:
        cache.delete_memoized(google_user_data, token)
        logger.warning(
            "Could not login with oauth. Trying again - {}".format(user_data))
        user_data = google_user_data(token, timeout=10)

    if not user_data or 'email' not in user_data:
        cache.delete_memoized(google_user_data, token)
        logger.warning("Auth Retry failed for token {} - {}".format(
            token, user_data))
        return None

    return user_from_email(user_data['email'])
コード例 #16
0
ファイル: admin.py プロジェクト: shivasheeshyadav/ok
def grade(bid):
    """ Used as a form submission endpoint. """
    backup = Backup.query.options(db.joinedload('assignment')).get(bid)
    if not backup:
        abort(404)
    if not Backup.can(backup, current_user, 'grade'):
        flash("You do not have permission to score this assignment.", "warning")
        abort(401)

    form = forms.GradeForm()
    score_kind = form.kind.data.strip().lower()
    is_composition = (score_kind == "composition")
    # TODO: Form should include redirect url instead of guessing based off tag

    if is_composition:
        form = forms.CompositionScoreForm()

    if not form.validate_on_submit():
        return grading_view(backup, form=form)

    score = Score(backup=backup, grader=current_user,
                  assignment_id=backup.assignment_id)
    form.populate_obj(score)
    db.session.add(score)
    db.session.commit()

    # Archive old scores of the same kind
    score.archive_duplicates()

    next_page = None
    flash_msg = "Added a {0} {1} score.".format(score.score, score_kind)

    # Find GradingTasks applicable to this score
    tasks = backup.grading_tasks
    for task in tasks:
        task.score = score
        cache.delete_memoized(User.num_grading_tasks, task.grader)

    db.session.commit()

    if len(tasks) == 1:
        # Go to next task for the current task queue if possible.
        task = tasks[0]
        next_task = task.get_next_task()
        next_route = '.composition' if is_composition else '.grading'
        # Handle case when the task is on the users queue
        if next_task:
            flash_msg += (" There are {0} tasks left. Here's the next submission:"
                          .format(task.remaining))
            next_page = url_for(next_route, bid=next_task.backup_id)
        else:
            flash_msg += " All done with grading for {}".format(backup.assignment.name)
            next_page = url_for('.grading_tasks')
    else:
        # TODO: Send task id or redirect_url in the grading form
        # For now, default to grading tasks
        next_page = url_for('.grading_tasks')

    flash(flash_msg, 'success')

    if not next_page:
        next_page = url_for('.assignment_queues', aid=backup.assignment_id,
                            cid=backup.assignment.course_id)
    return redirect(next_page)
コード例 #17
0
ファイル: models.py プロジェクト: xiaomeow/ok
 def unenroll(self):
     cache.delete_memoized(User.is_enrolled)
     db.session.delete(self)
コード例 #18
0
ファイル: admin.py プロジェクト: gratimax/ok
def grade(bid):
    """ Used as a form submission endpoint. """
    backup = Backup.query.options(db.joinedload('assignment')).get(bid)
    if not backup:
        abort(404)
    if not Backup.can(backup, current_user, 'grade'):
        flash("You do not have permission to score this assignment.", "warning")
        abort(401)

    form = forms.GradeForm()
    score_kind = form.kind.data.strip().lower()
    is_composition = (score_kind == "composition")
    # TODO: Form should include redirect url instead of guessing based off tag

    if is_composition:
        form = forms.CompositionScoreForm()

    if not form.validate_on_submit():
        return grading_view(backup, form=form)

    score = Score(backup=backup, grader=current_user,
                  assignment_id=backup.assignment_id)
    form.populate_obj(score)
    db.session.add(score)
    db.session.commit()

    # Archive old scores of the same kind
    score.archive_duplicates()

    next_page = None
    flash_msg = "Added a {0} {1} score.".format(score.score, score_kind)

    # Find GradingTasks applicable to this score
    tasks = backup.grading_tasks
    for task in tasks:
        task.score = score
        cache.delete_memoized(User.num_grading_tasks, task.grader)

    db.session.commit()

    if len(tasks) == 1:
        # Go to next task for the current task queue if possible.
        task = tasks[0]
        next_task = task.get_next_task()
        next_route = '.composition' if is_composition else '.grading'
        # Handle case when the task is on the users queue
        if next_task:
            flash_msg += (" There are {0} tasks left. Here's the next submission:"
                          .format(task.remaining))
            next_page = url_for(next_route, bid=next_task.backup_id)
        else:
            flash_msg += " All done with grading for {}".format(backup.assignment.name)
            next_page = url_for('.grading_tasks')
    else:
        # TODO: Send task id or redirect_url in the grading form
        # For now, default to grading tasks
        next_page = url_for('.grading_tasks')

    flash(flash_msg, 'success')

    if not next_page:
        next_page = url_for('.assignment_queues', aid=backup.assignment_id,
                            cid=backup.assignment.course_id)
    return redirect(next_page)