def test_ctf_started(self): tomorrow = now() + timedelta(1) s = Settings(ctf_start_date=tomorrow) assert not s.ctf_started s = Settings( ctf_start_date=datetime(2012, 1, 1, tzinfo=utc), ctf_end_date=now() + timedelta(1)) assert s.ctf_started
def test_current_state_started_login(self): t = self.make_team(active=True) self.dbsession.add(t) self.dbsession.flush() self.login(t.id) self.settings.ctf_start_date = now() - timedelta(1) self.settings.ctf_end_date = now() + timedelta(1) assert self.view.current_state == (CTF_STARTED, True)
def test_init(self): now_before = now() - timedelta(1) n = News() now_after = now() + timedelta(1) self.dbsession.add(n) self.dbsession.flush() self.dbsession.expire(n) assert n.timestamp > now_before assert n.timestamp < now_after
def test_defaults(self): now_before = now() - timedelta(1) m = self.make_massmail() self.dbsession.add(m) self.dbsession.flush() self.dbsession.expire(m) now_after = now() + timedelta(1) assert m.timestamp > now_before assert m.timestamp < now_after
def test_verify_token_inactive_team(self): self.settings.ctf_start_date = now() - timedelta(1) self.settings.ctf_end_date = now() + timedelta(1) t = self.make_team(active=False) self.dbsession.add(t) self.dbsession.flush() assert t.challenge_token self.request.matchdict['token'] = t.challenge_token ret = self.view.verify_token() assert ret.body == '0'
def _prepare(self, pyramid_request, view, template_lookup, get_template, dbsettings, countries): self.template_lookup = template_lookup self.get = get_template self.request = pyramid_request self.view = view self.load_template() self.countries = countries self.settings = dbsettings self.settings.ctf_end_date = now() + timedelta(1) self.settings.ctf_start_date = now() - timedelta(1) self.request.settings.ctf_start_date = now() - timedelta(1) self.request.settings.ctf_end_date = now() + timedelta(1) if not hasattr(self.request, 'team'): self.request.team = None
def test_verify_token_before_start(self): self.settings.ctf_start_date = now() + timedelta(1) t = self.make_team(active=True) self.dbsession.add(t) self.dbsession.flush() self.request.matchdict['token'] = t.challenge_token assert t.challenge_token assert self.view.verify_token().body == '0'
def seconds_until_end(self): if self.request.settings.archive_mode: raise ValueError("CTF is in archive mode. Cannot yield remaining " "seconds") end = self.request.settings.ctf_end_date countdown = int((end - now()).total_seconds()) if countdown <= 0: return 0 else: return countdown
def ctf_progress(self): if self.request.settings.archive_mode: return 1 end = self.request.settings.ctf_end_date start = self.request.settings.ctf_start_date total_time = (end - start).total_seconds() already_passed = (now() - start).total_seconds() progress = already_passed / total_time if progress >= 1: return 1 elif progress < 0: return 0 else: return progress
def _login(self, team): # Determine state of CTF settings = self.dbsession.query(Settings).one() if settings.ctf_start_date > now(): msg = "You are now logged in." else: msg = "You have been logged in." resp = self.app.get('/login') form = resp.form form['email'].value = team.email form['password'].value = team._real_password resp = form.submit() assert resp.status_int == 302 resp = resp.follow().follow() assert resp.status_int == 200 assert msg in resp.body return resp
def test_submit_solution_wrong(self): token = self.request.session.get_csrf_token() c = self.make_challenge(solution="Test", online=True, published=True) self.dbsession.add(c) t = self.make_team() self.dbsession.add(t) self.dbsession.flush() self.request.team = t self.login(t.id) self.request.POST = MultiDict(submit="submit", csrf_token=token, solution="Test1", challenge=str(c.id)) self.request.method = "POST" self.settings.ctf_end_date = now() + timedelta(1) ret = self.view.submit_solution() assert len(self.request.session.peek_flash('success')) == 0 assert len(self.request.session.peek_flash('error')) == 1 assert isinstance(ret, HTTPFound) assert self.dbsession.query(Submission).count() == 0
def test_challenge_solution_submit(self): token = self.request.session.get_csrf_token() c = self.make_challenge(solution="Test", online=True, published=True) t = self.make_team() self.request.team = t self.dbsession.add_all([c, t]) self.dbsession.flush() self.login(t.id) self.request.matchdict["id"] = c.id self.request.POST = MultiDict(submit="submit", csrf_token=token, solution="Test") self.request.method = "POST" self.settings.ctf_end_date = now() + timedelta(1) ret = self.view.challenge() assert len(self.request.session.peek_flash('success')) == 1 assert len(self.request.session.peek_flash('error')) == 0 assert isinstance(ret, HTTPFound) subm = self.dbsession.query(Submission).one() assert subm.challenge == c assert subm.team == t
def ctf_state(request, dbsettings, login_team, make_team, dbsession): ctf_state, login_state = request.param if ctf_state == CTF_BEFORE: dbsettings.ctf_start_date = now() + timedelta(1) dbsettings.ctf_end_date = now() + timedelta(2) elif ctf_state == CTF_STARTED: dbsettings.ctf_start_date = now() - timedelta(1) dbsettings.ctf_end_date = now() + timedelta(1) else: dbsettings.ctf_start_date = now() - timedelta(2) dbsettings.ctf_end_date = now() - timedelta(1) dbsettings.archive_mode = True t = make_team() dbsession.add(t) dbsession.flush() if login_state: login_team(t.id) return ctf_state, login_state, t
def test_now(): now_before = utc.localize(datetime.utcnow()) now_ = util.now() now_after = utc.localize(datetime.utcnow()) assert now_before <= now_ assert now_after >= now_
def test_ctf_state_before(self): tomorrow = now() + timedelta(1) s = Settings(ctf_start_date=tomorrow) assert s.ctf_state is CTF_BEFORE
def test_ctf_state_started(self): s = Settings( ctf_start_date=datetime(2012, 1, 1, tzinfo=utc), ctf_end_date=now() + timedelta(1)) assert s.ctf_state is CTF_STARTED
def test_global_announcement_wo_design_no_msg(self): self.settings.ctf_start_date = now() + timedelta(hours=1) self.test_global_announcement_w_design_no_msg()
def ctf_ended(self): from fluxscoreboard.util import now if self.ctf_end_date is None: return False return now() >= self.ctf_end_date
def ctf_before(dbsettings): dbsettings.ctf_start_date = now() + timedelta(1) dbsettings.ctf_end_date = now() + timedelta(2)
def check_submission(challenge, solution, team, settings): """ Check a solution for a challenge submitted by a team and add it to the database if it was correct. Args: ``challenge``: An instance of :class:`Challenge`, the challenge to check the solution for. ``solution``: A string, the proposed solution for the challenge. ``team``: Team that submitted the solution. Returns: A tuple of ``(result, msg)``. ``result`` indicates whether the solution was accpeted (and added to the database) or not. The message returns a string with either a result (if ``result == False``) or a congratulations message. """ # Perform all checks that filter out invalid submissions if settings.submission_disabled: return False, "Submission is currently disabled" if not settings.archive_mode and now() > settings.ctf_end_date: return False, "The CTF is over, no more solutions can be submitted." if not challenge.online: return False, "Challenge is offline." if challenge.manual: return False, "Credits for this challenge will be given manually." if challenge.dynamic: return False, "The challenge is dynamic, no submission possible." # help faggots solution = solution.strip() if solution.startswith('flag{'): solution = solution[5:-1] if challenge.solution != solution: return False, "Solution incorrect." # After this, the solution is correct and we can return True if settings.archive_mode: return True, ("Congratulations: That was the correct solution! " "However, since the scoreboard is in archive mode, you " "will not be awarded any points.") query = (DBSession.query(Submission.team_id). filter(Submission.challenge_id == challenge.id)) submissions = [id_ for id_, in query] if team.id in submissions: return False, "Already solved." solved_count = len(submissions) first_blood_pts, place_msg = first_blood_map.get(solved_count, (0, None)) if place_msg is not None: msg = 'Congratulations: You solved this challenge as %s!' % place_msg else: msg = 'Congratulations: That was the correct solution!' msg += (' How did you like this challenge? Please provide some feedback ' 'in the form below.') submission = Submission(additional_pts=first_blood_pts) submission.team_id = team.id submission.challenge = challenge DBSession.add(submission) team.base_score += challenge.base_points + first_blood_pts team.bonus_score += challenge.points - challenge.base_points return True, msg
def ctf_started(dbsettings, dbsession): dbsettings.ctf_start_date = now() - timedelta(1) dbsettings.ctf_end_date = now() + timedelta(1)
def test_check_submission_ctf_over(self): self.dbsettings.ctf_end_date = now() - timedelta(1) result, msg = check_submission(None, None, None, self.dbsettings) assert result is False assert msg == "The CTF is over, no more solutions can be submitted."
def ctf_during(self, dbsettings): dbsettings.ctf_start_date = now() - timedelta(1) dbsettings.ctf_end_date = now() + timedelta(1)
def ctf_end_date(dbsettings): dbsettings.ctf_end_date = now() + timedelta(1)
def ctf_started(self): from fluxscoreboard.util import now if self.ctf_start_date is None or self.ctf_end_date is None: return False now_ = now() return now_ >= self.ctf_start_date and now_ < self.ctf_end_date
def test_ctf_over(self): self.settings.ctf_end_date = now() - timedelta(hours=1) out = unicode(self.render()) assert "The CTF is over" in out assert "Enter solution for challenge" not in out
def test_ctf_started(self): self.settings.ctf_start_date = datetime(2012, 1, 1, tzinfo=utc) self.settings.ctf_end_date = util.now() + timedelta(1) assert display_design(self.request)
def ctf_ended(dbsettings): dbsettings.ctf_start_date = now() - timedelta(2) dbsettings.ctf_end_date = now() - timedelta(1)
def _make_news(**kw): kw.setdefault("timestamp", now() - timedelta(1)) return make_news(**kw)
def test_ctf_over(self): self.settings.ctf_end_date = now() - timedelta(hours=1) out = self.render() assert u"CTF is over" in out.text assert u"Enter solution" not in out.text