Beispiel #1
0
def submit_key(tid, pid, key, method, uid=None, ip=None):
    """
    User problem submission. Problem submission is inserted into the database.

    Args:
        tid: user's team id
        pid: problem's pid
        key: answer text
        method: submission method (e.g. 'game')
        uid: user's uid
        ip: user's ip
    Returns:
        A dict.
        correct: boolean
        points: number of points the problem is worth.
        message: message indicating the correctness of the key.
    """

    db = api.common.get_conn()
    validate(submission_schema, {"tid": tid, "pid": pid, "key": key})

    if pid not in get_unlocked_pids(tid, category=None):
        raise InternalException(
            "You can't submit flags to problems you haven't unlocked.")

    if pid in get_solved_pids(tid=tid):
        exp = WebException(
            "Flag correct: however, you have already received points for that flag."
        )
        exp.data = {'code': 'solved'}
        raise exp

    user = api.user.get_user(uid=uid)
    if user is None:
        raise InternalException("User submitting flag does not exist.")

    uid = user["uid"]

    result = grade_problem(pid, key, tid)

    problem = get_problem(pid=pid)

    submission = {
        'uid': uid,
        'tid': tid,
        'timestamp': datetime.utcnow(),
        'pid': pid,
        'ip': ip,
        'key': key,
        'method': method,
        'category': problem['category'],
        'correct': result['correct'],
    }

    if (key, pid) in [(submission["key"], submission["pid"])
                      for submission in get_submissions(tid=tid)]:
        exp = WebException(
            "Flag incorrect: please note that you or your team have already submitted this flag."
        )
        exp.data = {'code': 'repeat'}
        raise exp

    db.submissions.insert(submission)

    if submission["correct"]:
        api.cache.invalidate_memoization(api.stats.get_score,
                                         {"kwargs.tid": tid},
                                         {"kwargs.uid": uid})
        api.cache.invalidate_memoization(get_unlocked_pids, {"args": tid})
        api.cache.invalidate_memoization(get_solved_problems,
                                         {"kwargs.tid": tid},
                                         {"kwargs.uid": uid})

        api.cache.invalidate_memoization(api.stats.get_score_progression,
                                         {"kwargs.tid": tid},
                                         {"kwargs.uid": uid})

        api.achievement.process_achievements("submit", {
            "uid": uid,
            "tid": tid,
            "pid": pid
        })

    return result
Beispiel #2
0
def submit_key(tid, pid, key, uid=None, ip=None):
    """
    User problem submission. Problem submission is inserted into the database.

    Args:
        tid: user's team id
        pid: problem's pid
        key: answer text
        uid: user's uid
    Returns:
        A dict.
        correct: boolean
        points: number of points the problem is worth.
        message: message returned from the grader.
    """

    db = api.common.get_conn()
    validate(submission_schema, {"tid": tid, "pid": pid, "key": key})

    if pid not in get_unlocked_pids(tid):
        raise InternalException("You can't submit flags to problems you haven't unlocked.")

    if pid in get_solved_pids(tid=tid):
        exp = WebException("You have already solved this problem.")
        exp.data = {'code': 'solved'}
        raise exp

    user = api.user.get_user(uid=uid)
    if user is None:
        raise InternalException("User submitting flag does not exist.")

    uid = user["uid"]

    result = grade_problem(pid, key, tid)

    problem = get_problem(pid=pid)

    eligibility = api.team.get_team(tid=tid)['eligible']

    submission = {
        'uid': uid,
        'tid': tid,
        'timestamp': datetime.utcnow(),
        'pid': pid,
        'ip': ip,
        'key': key,
        'eligible': eligibility,
        'category': problem['category'],
        'correct': result['correct']
    }

    if (key, pid) in [(submission["key"], submission["pid"]) for submission in  get_submissions(tid=tid)]:
        exp = WebException("You or one of your teammates has already tried this solution.")
        exp.data = {'code': 'repeat'}
        raise exp

    db.submissions.insert(submission)

    if submission["correct"]:
        api.cache.invalidate_memoization(api.stats.get_score, {"kwargs.tid":tid}, {"kwargs.uid":uid})
        api.cache.invalidate_memoization(get_unlocked_pids, {"args":tid})
        api.cache.invalidate_memoization(get_solved_pids, {"kwargs.tid":tid}, {"kwargs.uid":uid})

        api.cache.invalidate_memoization(api.stats.get_score_progression, {"kwargs.tid":tid}, {"kwargs.uid":uid})

        api.achievement.process_achievements("submit", {"uid": uid, "tid": tid, "pid": pid})

    return result
Beispiel #3
0
def submit_key(tid, pid, key, uid=None, ip=None):
    """
    User problem submission. Problem submission is inserted into the database.

    Args:
        tid: user's team id
        pid: problem's pid
        key: answer text
        uid: user's uid
    Returns:
        A dict.
        correct: boolean
        points: number of points the problem is worth.
        message: message returned from the grader.
    """

    db = api.common.get_conn()
    validate(submission_schema, {"tid": tid, "pid": pid, "key": key})

    if pid not in get_unlocked_pids(tid):
        raise InternalException("You can't submit flags to problems you haven't unlocked.")

    if pid in get_solved_pids(tid=tid):
        exp = WebException("You have already solved this problem.")
        exp.data = {'code': 'solved'}
        raise exp

    user = api.user.get_user(uid=uid)
    if user is None:
        raise InternalException("User submitting flag does not exist.")

    uid = user["uid"]

    result = grade_problem(pid, key, tid)

    problem = get_problem(pid=pid)

    eligibility = api.team.get_team(tid=tid)['eligible']

    submission = {
        'uid': uid,
        'tid': tid,
        'timestamp': datetime.utcnow(),
        'pid': pid,
        'ip': ip,
        'key': key,
        'eligible': eligibility,
        'category': problem['category'],
        'correct': result['correct']
    }

    if (key, pid) in [(submission["key"], submission["pid"]) for submission in  get_submissions(tid=tid)]:
        exp = WebException("You or one of your teammates has already tried this solution.")
        exp.data = {'code': 'repeat'}
        raise exp

    db.submissions.insert(submission)

    if submission["correct"]:
        api.cache.invalidate_memoization(api.stats.get_score, {"kwargs.tid":tid}, {"kwargs.uid":uid})
        api.cache.invalidate_memoization(get_unlocked_pids, {"args":tid})
        api.cache.invalidate_memoization(get_solved_pids, {"kwargs.tid":tid}, {"kwargs.uid":uid})

        api.cache.invalidate_memoization(api.stats.get_score_progression, {"kwargs.tid":tid}, {"kwargs.uid":uid})

        api.achievement.process_achievements("submit", {"uid": uid, "tid": tid, "pid": pid})

    return result
Beispiel #4
0
def request_hint(tid, pid, uid=None, ip=None):
    """
    User hint request. Problem hint requests are inserted into the database.

    Args:
        tid: user's team id
        pid: problem's pid
        uid: user's uid
    Returns:
        A dict.
        points: number of points deducted
        hint: message returned from the grader.
    """

    db = api.common.get_conn()
    validate(hint_request_schema, {"tid": tid, "pid": pid})

    if pid not in get_unlocked_pids(tid):
        raise InternalException("You can't request hints to problems you haven't unlocked.")

    if pid in get_solved_pids(tid=tid):
        exp = WebException("You have already solved this problem.")
        exp.data = {'code': 'solved'}
        raise exp

    user = api.user.get_user(uid=uid)
    if user is None:
        raise InternalException("User submitting flag does not exist.")

    uid = user["uid"]

    problem = get_problem(pid=pid)

    grader = get_grader(pid)
    hints = grader.get_hints()

    if not hints :
        exp = WebException("No hints available for this problem... good luck!")
        exp.data = {'code': 'repeat'}
        raise exp

    hint_requests = get_hint_requests(pid=pid, tid=tid)

    eligibility = api.team.get_team(tid=tid)['eligible']

    if len(hint_requests) >= len(hints) :
        exp = WebException("You've already requested all available hints.")
        exp.data = {'code': 'repeat'}
        raise exp

    new_hint_points = hints[len(hint_requests)][0]
    new_hint = hints[len(hint_requests)][1]

    hint_request = {
        'uid': uid,
        'tid': tid,
        'timestamp': datetime.utcnow(),
        'hint': new_hint,
        'points_deducted': new_hint_points,
        'ip': ip,
        'eligible': eligibility,
        'pid': pid,
        'category': problem['category']
    }

    db.hint_requests.insert(hint_request)

    api.cache.invalidate_memoization(api.stats.get_score, {"kwargs.tid":tid}, {"kwargs.uid":uid})
    api.cache.invalidate_memoization(get_unlocked_pids, {"args":tid})
    api.cache.invalidate_memoization(get_solved_pids, {"kwargs.tid":tid}, {"kwargs.uid":uid})

    api.cache.invalidate_memoization(api.stats.get_score_progression, {"kwargs.tid":tid}, {"kwargs.uid":uid})

    ret = WebSuccess(new_hint)
    ret.data = {'points': new_hint_points, 'hint': new_hint }
    return ret