Example #1
0
def verify_email(request, session):
    """Performs the email address verification.

    Gets a token from the url parameters, if the token is found in a team object in the database
    the new password is hashed and set, the token is then removed and an appropriate response is returned.
    """
    token = request.args.get('token', None)
    if token is None or token == '':
        return {"status": 0, "message": "验证信息不能为空."}
    token = token.encode('utf8')

    team = db.teams.find_one({'emailverifytoken': token})
    if team is None:
        return {"status": 0, "message": "验证信息无效."}
    try:
        db.teams.update({'tid': team['tid']}, {'$set': {'email_verified': True}})
        db.teams.update({'tid': team['tid']}, {'$unset': {'emailverifytoken': 1}})
    except:
        return {"status": 0, "message": "验证邮箱失败. 请联系管理员."}
    if is_zju_email(team['email']):
        cache.delete('verified_teams_zju')
    else:
        cache.delete('verified_teams_public')
    session['tid'] = team['tid']
    session['teamname'] = team['teamname']
    session['is_zju_user'] = is_zju_email(team['email'])
    return {"status": 1, "message": "邮箱已被验证成功."}
Example #2
0
def reset_password(request):
    """Perform the password update operation.

    Gets a token and new password from a submitted form, if the token is found in a team object in the database
    the new password is hashed and set, the token is then removed and an appropriate response is returned.
    """
    token = request.form.get('token', None)
    newpw = request.form.get('newpw', None)
    if token is None or token == '':
        return {"status": 0, "message": "密码重设密钥不能为空."}
    if newpw is None or newpw == '':
        return {"status": 0, "message": "新密码不能为空."}
    token = token.encode('utf8')
    newpw = newpw.encode('utf8')

    team = db.teams.find_one({'passrestoken': token})
    if team is None:
        return {"status": 0, "message": "密码重设密钥无效."}
    try:
        db.teams.update({'tid': team['tid']}, {'$set': {'pwhash': bcrypt.hashpw(newpw, bcrypt.gensalt(8))}})
        db.teams.update({'tid': team['tid']}, {'$unset': {'passrestoken': 1}})
        db.teams.update({'tid': team['tid']}, {'$set': {'email_verified': True}})
    except:
        return {"status": 0, "message": "重设密码出现错误. 请重试或联系管理员."}
    if not team['email_verified']:
        if is_zju_email(team['email']):
            cache.delete('verified_teams_zju')
        else:
            cache.delete('verified_teams_public')
    return {"status": 1, "message": "密码已被重设."}
Example #3
0
def submit_problem(tid, request):
    """Handle problem submission.

    Gets the key and pid from the submitted problem, calls the respective grading function if the values aren't empty.
    If correct all relevant cache values are cleared. The submission is the inserted into the database
    (an attempt is made). A relevant message is returned if the problem has already been solved or the answer
    has been tried.
    """
    pid = request.form.get('pid', '').strip()
    key = request.form.get('key', '').strip()
    correct = False
    if pid == '':
        return {"status": 0, "points": 0, "message": "Problem ID cannot be empty."}
    if key == '':
        return {"status": 0, "points": 0, "message": "Answer cannot be empty."}
    if pid not in [p['pid'] for p in load_unlocked_problems(tid)]:
        return {"status": 0, "points": 0, "message": "You cannot submit problems you have not unlocked."}
    prob = db.problems.find_one({"pid": pid})
    if prob is None:
        return {"status": 0, "points": 0, "message": "Problem ID not found in the database."}

    if not prob.get('autogen', False):  # This is a standard problem, not auto-generated
        (correct, message) = imp.load_source(prob['grader'][:-3], "./graders/" + prob['grader']).grade(tid, key)
    else:  # This is an auto-generated problem, grading is different.
        team = db.teams.find_one({'tid': tid})
        grader_type = prob.get('grader', 'file')
        if grader_type == 'file':
            (correct, message) = imp.load_source(team['probinstance'][pid]['grader'][:-3],
                                                 team['probinstance'][pid]['grader']).grade(tid, key)
        elif grader_type == 'key':
            correct = team['probinstance'][pid]['key'] == key
            message = prob.get('correct_msg', 'Correct!') if correct else prob.get('wrong_msg', 'Nope!')
    submission = {'tid': tid,
                  'timestamp': datetime.now(),
                  'pid': pid,
                  'ip': request.headers.get('X-Real-IP', None),
                  'key': key,
                  'correct': correct}
    if correct:
        cache.delete('unlocked_' + tid)  # Clear the unlocked problem cache as it needs updating
        cache.delete('solved_' + tid)  # Clear the list of solved problems
        cache.delete('teamscore_' + tid)  # Clear the team's cached score
        cache.delete('lastsubdate_' + tid)
        try:
            db.submissions.insert(submission)
        except DuplicateKeyError:
            return {"status": 0, "points": 0, "message": "You have already solved this problem!"}
    else:
        try:
            db.submissions.insert(submission)
        except DuplicateKeyError:
            return {"status": 0, "points": 0, "message": "You already tried that!"}
    return {"status": 1 if correct else 0, "points": prob.get('basescore', 0), "message": message}
Example #4
0
def submit_problem(tid, request, is_zju_user):
    """Handle problem submission.

    Gets the key and pid from the submitted problem, calls the respective grading function if the values aren't empty.
    If correct all relevant cache values are cleared. The submission is the inserted into the database
    (an attempt is made). A relevant message is returned if the problem has already been solved or the answer
    has been tried.
    """
    # Nginx Configuration Fixed --libmaru
    """
    import common
    common.log('Hello, '+request.remote_addr, 'ERROR')
    """

    """
    response = captcha.submit(
        request.form.get('recaptcha_challenge', ''),
        request.form.get('recaptcha_response', ''),
        '6LcPFPESAAAAAIkncbbAOfUi6sTSrMMxKVA9EcMq',
        request.remote_addr
    )

    if not response.is_valid:
        return {"status": 0, "points": 0, "message": "验证码不正确."}
    """

    t_interval = 10
    last_submitted = cache.get('last_submitted_' + tid)
    if not last_submitted:
        cache.set('last_submitted_' + tid, True, t_interval)
    else:
        return {"status": 0, "points": 0, "message": "相邻提交之间隔须多于%d秒, 请稍后再试." % t_interval}

    pid = request.form.get('pid', '')
    key = request.form.get('key', '')
    if pid == '':
        return {"status": 0, "points": 0, "message": "题目名字不能为空."}
    if key == '':
        return {"status": 0, "points": 0, "message": "答案不能为空."}
    #if pid not in [p['pid'] for p in load_unlocked_problems(tid)]:
    #    return {"status": 0, "points": 0, "message": "You cannot submit problems you have not unlocked."}
    pid = pid.encode('utf8').strip()
    # key = key.encode('utf8').strip()
    prob = cache.get('problem_' + pid)
    if prob is None:
        prob = db.problems.find_one({"pid": pid})
        if prob is None:
            return {"status": 0, "points": 0, "message": "未找到题目'%s'." %pid}
        del prob['_id']
        cache.set('problem_' + pid, json.dumps(prob), 60 * 60)
    else:
        prob = json.loads(prob)

    correct = False
    grader_type = prob.get('grader-type', 'key')
    if grader_type == 'file':
        (correct, message) = imp.load_source(prob['grader'][:-3], "./graders/" + prob['grader']).grade(tid, key)
    elif grader_type == 'key':
        correct = prob['key'] == key
        message = prob.get('correct_msg', '回答正确!') if correct else prob.get('wrong_msg', '回答错误!')
    message = message.encode('utf8')
    
    tstamp = utilities.timestamp(datetime.utcnow())
    submission = {'tid': tid,
                  'timestamp': tstamp,
                  'pid': pid,
                  'ip': request.headers.get('X-Real-IP', None),
                  'key': key,
                  'correct': correct}

    if correct:
        #cache.delete('unlocked_' + tid)  # Clear the unlocked problem cache as it needs updating
        cache.delete('solved_' + tid)  # Clear the list of solved problems
        cache.delete('problems_' + tid)
        if is_zju_user:
            cache.delete('scoreboard_zju')  
        else:
            cache.delete('scoreboard_public')  
        cache.delete('teamscore_' + tid)  # Clear the team's cached score
        cache.delete('lastsubdate_' + tid)
        try:
            db.submissions.insert(submission)
        except DuplicateKeyError:
            return {"status": 0, "points": 0, "message": "你已解决此题!"}
    else:
        try:
            db.submissions.insert(submission)
        except DuplicateKeyError:
            return {"status": 0, "points": 0, "message": "你已提交过这一错误答案!"}
    return {"status": 1 if correct else 0, "points": prob.get('basescore', 0), "message": message}
Example #5
0
def submit_problem(tid, request):
    """Handle problem submission.

    Gets the key and pid from the submitted problem, calls the respective grading function if the values aren't empty.
    If correct all relevant cache values are cleared. The submission is the inserted into the database
    (an attempt is made). A relevant message is returned if the problem has already been solved or the answer
    has been tried.
    """
    pid = request.form.get('pid', '').strip()
    key = request.form.get('key', '').strip()
    correct = False
    if pid == '':
        return {
            "status": 0,
            "points": 0,
            "message": "Problem ID cannot be empty."
        }
    if key == '':
        return {"status": 0, "points": 0, "message": "Answer cannot be empty."}
    if pid not in [p['pid'] for p in load_unlocked_problems(tid)]:
        return {
            "status": 0,
            "points": 0,
            "message": "You cannot submit problems you have not unlocked."
        }
    prob = db.problems.find_one({"pid": pid})
    if prob is None:
        return {
            "status": 0,
            "points": 0,
            "message": "Problem ID not found in the database."
        }

    if not prob.get('autogen',
                    False):  # This is a standard problem, not auto-generated
        (correct, message) = imp.load_source(prob['grader'][:-3],
                                             "./graders/" +
                                             prob['grader']).grade(tid, key)
    else:  # This is an auto-generated problem, grading is different.
        team = db.teams.find_one({'tid': tid})
        grader_type = prob.get('grader', 'file')
        if grader_type == 'file':
            (correct, message) = imp.load_source(
                team['probinstance'][pid]['grader'][:-3],
                team['probinstance'][pid]['grader']).grade(tid, key)
        elif grader_type == 'key':
            correct = team['probinstance'][pid]['key'] == key
            message = prob.get('correct_msg',
                               'Correct!') if correct else prob.get(
                                   'wrong_msg', 'Nope!')
    submission = {
        'tid': tid,
        'timestamp': datetime.now(),
        'pid': pid,
        'ip': request.headers.get('X-Real-IP', None),
        'key': key,
        'correct': correct
    }
    if correct:
        cache.delete(
            'unlocked_' +
            tid)  # Clear the unlocked problem cache as it needs updating
        cache.delete('solved_' + tid)  # Clear the list of solved problems
        cache.delete('teamscore_' + tid)  # Clear the team's cached score
        cache.delete('lastsubdate_' + tid)
        try:
            db.submissions.insert(submission)
        except DuplicateKeyError:
            return {
                "status": 0,
                "points": 0,
                "message": "You have already solved this problem!"
            }
    else:
        try:
            db.submissions.insert(submission)
        except DuplicateKeyError:
            return {
                "status": 0,
                "points": 0,
                "message": "You already tried that!"
            }
    return {
        "status": 1 if correct else 0,
        "points": prob.get('basescore', 0),
        "message": message
    }