예제 #1
0
    def post(self):
        data = flask.request.get_json()
        unlocked = data.get('unlocked', False)
        answer = utils.normalize_input(data['answer'])
        chall = models.Challenge.create(
            data['name'],
            data['description'],
            data['points'],
            '',
            data['cat_slug'],
            unlocked,
            data.get('validator', validators.GetDefaultValidator()))
        validator = validators.GetValidatorForChallenge(chall)
        validator.change_answer(answer)
        if 'attachments' in data:
            chall.set_attachments(data['attachments'])
        if 'prerequisite' in data:
            chall.set_prerequisite(data['prerequisite'])
        if 'tags' in data:
            chall.set_tags(data['tags'])

        if unlocked and utils.GameTime.open():
            news = 'New challenge created: "%s"' % chall.name
            models.News.game_broadcast(message=news)

        models.commit()
        app.logger.info('Challenge %s created by %r.',
                        chall, models.User.current())
        return chall
예제 #2
0
 def testStaticValidator(self):
     chall = ChallengeStub(None)
     validator = validators.GetValidatorForChallenge(chall)
     self.assertFalse(validator.validate_answer('fooabc', None))
     validator.change_answer('fooabc')
     self.assertTrue(validator.validate_answer('fooabc', None))
     self.assertFalse(validator.validate_answer('abcfoo', None))
예제 #3
0
    def put(self, challenge_id):
        challenge = models.Challenge.query.get_or_404(challenge_id)
        data = flask.request.get_json()
        old_unlocked = challenge.unlocked
        for field in (
                'name', 'description', 'points',
                'cat_slug', 'unlocked', 'weight', 'validator'):
            setattr(
                challenge, field, data.get(field, getattr(challenge, field)))
        if 'answer' in data and data['answer']:
            answer = utils.normalize_input(data['answer'])
            validator = validators.GetValidatorForChallenge(challenge)
            validator.change_answer(answer)
        if 'attachments' in data:
            challenge.set_attachments(data['attachments'])
        if 'prerequisite' in data:
            challenge.set_prerequisite(data['prerequisite'])
        else:
            challenge.prerequisite = ''
        if 'tags' in data:
            challenge.set_tags(data['tags'])
        if challenge.unlocked and not old_unlocked:
            news = 'Challenge "%s" unlocked!' % challenge.name
            models.News.game_broadcast(message=news)

        app.logger.info('Challenge %s updated by %r.',
                        challenge, models.User.current())

        models.commit()
        cache.clear()
        return challenge
예제 #4
0
def test_answer(cid, answer):
    """Tests an answer, returns Truthiness of answer."""
    try:
        challenge = models.Challenge.query.get(cid)
        validator = validators.GetValidatorForChallenge(challenge)
        return validator.validate_answer(answer, None)
    except errors.IntegrityError:
        return False
예제 #5
0
 def testCaseStaticValidator(self):
     chall = ChallengeStub(None, validator='static_pbkdf2_ci')
     validator = validators.GetValidatorForChallenge(chall)
     self.assertFalse(validator.validate_answer('foo', None))
     validator.change_answer('FooBar')
     for test in ('FooBar', 'foobar', 'FOOBAR', 'fooBAR'):
         self.assertTrue(validator.validate_answer(test, None),
                         msg='Case failed: {}'.format(test))
     for test in ('barfoo', 'bar', 'foo', None):
         self.assertFalse(validator.validate_answer(test, None),
                          msg='Case failed: {}'.format(test))
예제 #6
0
 def setUp(self):
     super(NonceValidatorTest, self).setUp()
     self.chall = models.Challenge.create('foo',
                                          'bar',
                                          100,
                                          '',
                                          unlocked=True,
                                          validator='nonce_166432')
     self.validator = validators.GetValidatorForChallenge(self.chall)
     self.validator.change_answer('secret123')
     self.team = models.Team.create('footeam')
     models.commit()
예제 #7
0
def submit_answer(cid, answer):
    """Submits an answer.

    Returns:
      Number of points awarded for answer.
    """
    correct = 'WRONG'
    team = models.Team.current()
    if not team:
        raise errors.AccessDeniedError('No team!')
    try:
        challenge = models.Challenge.query.get(cid)
        if not challenge.unlocked_for_team(team):
            raise errors.AccessDeniedError('Challenge is locked!')
        validator = validators.GetValidatorForChallenge(challenge)
        if validator.validate_answer(answer, team):
            ans = models.Answer.create(challenge, team, answer)

            if utils.GameTime.over():
                correct = 'CORRECT (Game Over)'
            else:
                team.score += ans.current_points
                correct = 'CORRECT'

            team.last_solve = datetime.datetime.utcnow()
            models.ScoreHistory.add_entry(team)
            challenge.update_answers(exclude_team=team)

            if utils.GameTime.over():
                return 0
            else:
                return ans.current_points
        else:
            raise errors.InvalidAnswerError('Really?  Haha no....')
    except errors.IntegrityError:
        models.db.session.rollback()
        raise
    finally:
        user = models.User.current()
        app.challenge_log.info(
            'Player %s <%s>(%d)/Team %s(%d) submitted '
            '"%s" for Challenge %s<%d>: %s', user.nick, user.email, user.uid,
            team.name, team.tid, answer, challenge.name, challenge.cid,
            correct)
예제 #8
0
def submit_answer(cid, answer, token):
    """Submits an answer.

    Args:
      cid: The ID of the challenge.
      answer: The answer to check.
      token: Provided proof of work token.

    Returns:
      Number of points awarded for answer.
    """
    correct = 'WRONG'
    nbits = app.config.get('PROOF_OF_WORK_BITS', 0)
    if nbits and not utils.validate_proof_of_work(answer, token, nbits):
        raise errors.InvalidAnswerError('Bad proof of work token!')
    team = models.Team.current()
    if not team:
        raise errors.AccessDeniedError('No team!')
    try:
        challenge = models.Challenge.query.get(cid)
        if not challenge.unlocked_for_team(team):
            raise errors.AccessDeniedError('Challenge is locked!')
        validator = validators.GetValidatorForChallenge(challenge)
        if validator.validate_answer(answer, team):
            points = save_team_answer(challenge, team, answer)
            if utils.GameTime.over():
                correct = 'CORRECT (Game Over)'
            else:
                correct = 'CORRECT'
            return points
        else:
            raise errors.InvalidAnswerError('Really?  Haha no....')
    except (errors.IntegrityError, errors.FlushError) as exc:
        app.logger.exception('Error saving flag: %s', exc)
        models.db.session.rollback()
        raise
    finally:
        user = models.User.current()
        app.challenge_log.info(
            'Player %s <%s>(%d)/Team %s(%d) submitted '
            '"%s" for Challenge %s<%d>: %s', user.nick, user.email, user.uid,
            team.name, team.tid, answer, challenge.name, challenge.cid,
            correct)
예제 #9
0
def submit_answer(cid, answer):
    """Submits an answer.

    Args:
      cid: The ID of the challenge.
      answer: The answer to check.

    Returns:
      Number of points awarded for answer.
    """
    correct = 'WRONG'
    team = models.Team.current()
    if not team:
        raise errors.AccessDeniedError('No team!')
    try:
        challenge = models.Challenge.query.get(cid)
        if not challenge.unlocked_for_team(team):
            raise errors.AccessDeniedError('Challenge is locked!')
        validator = validators.GetValidatorForChallenge(challenge)
        if validator.validate_answer(answer, team):
            points = save_team_answer(challenge, team, answer)
            if utils.GameTime.over():
                correct = 'CORRECT (Game Over)'
            else:
                correct = 'CORRECT'
            return points
        else:
            raise errors.InvalidAnswerError('Really?  Haha no....')
    except errors.IntegrityError:
        models.db.session.rollback()
        raise
    finally:
        user = models.User.current()
        app.challenge_log.info(
            'Player %s <%s>(%d)/Team %s(%d) submitted '
            '"%s" for Challenge %s<%d>: %s', user.nick, user.email, user.uid,
            team.name, team.tid, answer, challenge.name, challenge.cid,
            correct)
예제 #10
0
 def makeValidator(self, regex):
     """Construct a validator."""
     chall = ChallengeStub(regex, validator='regex_ci')
     return validators.GetValidatorForChallenge(chall)