def scores(): json = {'data': [], "succes": True} if scores_visible() and not authed(): return redirect(url_for('auth.login', next=request.path)) if not scores_visible(): return jsonify(json) standings = get_standings() for i, x in enumerate(standings): score = "" for j in x['solves']: score += str(j['score']) + '</td><td class="chalmark">' score += str(x['score']) json['data'].append({ "account_type": "team", 'pos': i + 1, "score": score, "name": escape(x['name']), "account_url": "/teams/", "member": [{ "score": x['score'], "id": x['teamid'], "name": escape(x['name']), }] }) return jsonify(json)
def scoreboard_view(): if scores_visible() and not authed(): return redirect(url_for('auth.login', next=request.path)) if not scores_visible(): return render_template('scoreboard.html', errors=['Scores are currently hidden']) standings = get_standings() challenges, categories = get_challenges() return render_template('scoreboard.html', standings=standings, score_frozen=is_scoreboard_frozen(), mode='users' if is_users_mode() else 'teams', challenges=challenges, categories=categories, theme=ctf_theme())
def scores(): json = {'standings': []} if scores_visible() and not authed(): return redirect(url_for('auth.login', next=request.path)) if not scores_visible(): return jsonify(json) standings = get_standings() for i, x in enumerate(standings): json['standings'].append({'pos': i + 1, 'id': x['name'], 'team': x['name'], 'score': int(x['score']), 'solves': x['solves']}) return jsonify(json)
def get(self, user_id): if user_id == 'me': if not authed(): abort(403) user = get_current_user() else: if accounts_visible() is False or scores_visible() is False: abort(404) user = Users.query.filter_by(id=user_id).first_or_404() if (user.banned or user.hidden) and is_admin() is False: abort(404) fails = user.get_fails(admin=is_admin()) view = 'user' if not is_admin() else 'admin' response = SubmissionSchema(view=view, many=True).dump(fails) if response.errors: return {'success': False, 'errors': response.errors}, 400 if is_admin(): data = response.data else: data = [] count = len(response.data) return {'success': True, 'data': data, 'meta': {'count': count}}
def get(self, team_id): if team_id == 'me': if not authed(): abort(403) team = get_current_team() else: if accounts_visible() is False or scores_visible() is False: abort(404) team = Teams.query.filter_by(id=team_id).first_or_404() if (team.banned or team.hidden) and is_admin() is False: abort(404) fails = team.get_fails(admin=is_admin()) view = 'admin' if is_admin() else 'user' schema = SubmissionSchema(view=view, many=True) response = schema.dump(fails) if response.errors: return {'success': False, 'errors': response.errors}, 400 if is_admin(): data = response.data else: data = [] count = len(response.data) return {'success': True, 'data': data, 'meta': {'count': count}}
def get(self, team_id): if team_id == "me": if not authed(): abort(403) team = get_current_team() fails = team.get_fails(admin=True) else: if accounts_visible() is False or scores_visible() is False: abort(404) team = Teams.query.filter_by(id=team_id).first_or_404() if (team.banned or team.hidden) and is_admin() is False: abort(404) fails = team.get_fails(admin=is_admin()) view = "admin" if is_admin() else "user" schema = SubmissionSchema(view=view, many=True) response = schema.dump(fails) if response.errors: return {"success": False, "errors": response.errors}, 400 if is_admin(): data = response.data else: data = [] count = len(response.data) return {"success": True, "data": data, "meta": {"count": count}}
def multi_scoreboard(sb=None): if sb == None: sb = 'Global' infos = get_infos() if config.is_scoreboard_frozen(): infos.append("Scoreboard has been frozen") if is_admin() is True and scores_visible() is False: infos.append("Scores are not currently visible to users") standings = get_standings() teams = [] scoreboards = ["Global"] for t in Teams.query.all(): if sb == "Global" and (t.name not in teams): teams.append(t.name) for f in t.fields: if f.name not in scoreboards: scoreboards.append(f.name) if f.name == sb and (t.name not in teams): teams.append(t.name) if sb not in scoreboards: abort(404) filtered_standings = [st for st in standings if st[2] in teams] return render_template("multi_scoreboard.html", standings=filtered_standings, infos=infos, scoreboards=scoreboards, scoreboard=sb)
def get(self, user_id): if user_id == "me": if not authed(): abort(403) user = get_current_user() fails = user.get_fails(admin=True) else: if accounts_visible() is False or scores_visible() is False: abort(404) user = Users.query.filter_by(id=user_id).first_or_404() if (user.banned or user.hidden) and is_admin() is False: abort(404) fails = user.get_fails(admin=is_admin()) view = "user" if not is_admin() else "admin" response = SubmissionSchema(view=view, many=True).dump(fails) if response.errors: return {"success": False, "errors": response.errors}, 400 if is_admin(): data = response.data else: data = [] count = len(response.data) return {"success": True, "data": data, "meta": {"count": count}}
def place(self): from CTFd.utils.config.visibility import scores_visible if scores_visible(): return self.get_place(admin=False) else: return None
def get(self, team_id): if team_id == 'me': if not authed(): abort(403) team = get_current_team() else: if accounts_visible() is False or scores_visible() is False: abort(404) team = Teams.query.filter_by(id=team_id).first_or_404() awards = team.get_awards( admin=is_admin() ) schema = AwardSchema(many=True) response = schema.dump(awards) if response.errors: return { 'success': False, 'errors': response.errors }, 400 return { 'success': True, 'data': response.data }
def get(self, team_id): if team_id == 'me': if not authed(): abort(403) team = get_current_team() else: if accounts_visible() is False or scores_visible() is False: abort(404) team = Teams.query.filter_by(id=team_id).first_or_404() solves = team.get_solves( admin=is_admin() ) view = 'admin' if is_admin() else 'user' schema = SubmissionSchema(view=view, many=True) response = schema.dump(solves) if response.errors: return { 'success': False, 'errors': response.errors }, 400 return { 'success': True, 'data': response.data }
def scoreslist(count=10): json = {"success": True, "data": {}} if scores_visible() and not authed(): return redirect(url_for('auth.login', next=request.path)) if not scores_visible(): return jsonify(json) standings = get_standings() for i, x in enumerate(standings[:10]): solves = (db.session.query( Solves.challenge_id, Challenges.value, Solves.date).join( Challenges, Solves.challenge_id == Challenges.id).filter( Challenges.category.in_( x['cat'])).filter(Solves.team_id == x['teamid'])) freeze = utils.get_config('freeze') if freeze: freeze = unix_time_to_utc(freeze) if x['teamid'] != session.get('id'): solves = solves.filter(Solves.date < freeze) solves = solves.all() #print(x['teamid'],'Stat Solve',solves) sol = [] for s in solves: sol.append({ 'account_id': x['teamid'], 'challenge_id': s[0], 'date': s[2], 'team_id': x['teamid'], 'user_id': x['teamid'], 'value': s[1] }) sol = sorted(sol, key=lambda i: i["date"]) json['data'].update({ str(i + 1): { 'id': x['teamid'], 'name': escape(x['name']), 'solves': sol } }) return jsonify(json)
def listing(): infos = get_infos() if config.is_scoreboard_frozen(): infos.append("Результаты заморожены") if is_admin() is True and scores_visible() is False: infos.append("Результаты сейчас не отображаются для участников") standings = get_standings() return render_template("scoreboard.html", standings=standings, infos=infos)
def listing(): infos = get_infos() if config.is_scoreboard_frozen(): infos.append("Scoreboard has been frozen") if is_admin() is True and scores_visible() is False: infos.append("Scores are not currently visible to users") standings = get_standings() return render_template("scoreboard.html", standings=standings, infos=infos)
def get(self, challenge_id): if is_admin(): chal = Challenges.query.filter(Challenges.id == challenge_id).first_or_404() else: chal = Challenges.query.filter( Challenges.id == challenge_id, and_(Challenges.state != 'hidden', Challenges.state != 'locked') ).first_or_404() chal_class = get_chal_class(chal.type) tags = [ tag['value'] for tag in TagSchema( "user", many=True).dump( chal.tags).data] files = [f.location for f in chal.files] unlocked_hints = set() hints = [] if authed(): user = get_current_user() unlocked_hints = set([u.target for u in HintUnlocks.query.filter_by( type='hints', account_id=user.account_id)]) for hint in Hints.query.filter_by(challenge_id=chal.id).all(): if hint.id in unlocked_hints or ctf_ended(): hints.append({'id': hint.id, 'cost': hint.cost, 'content': hint.content}) else: hints.append({'id': hint.id, 'cost': hint.cost}) response = chal_class.read(challenge=chal) Model = get_model() if scores_visible() is True and accounts_visible() is True: solves = Solves.query\ .join(Model, Solves.account_id == Model.id)\ .filter(Solves.challenge_id == chal.id, Model.banned == False, Model.hidden == False)\ .count() response['solves'] = solves else: response['solves'] = None response['files'] = files response['tags'] = tags response['hints'] = hints db.session.close() return { 'success': True, 'data': response }
def listing(): infos = get_infos() if config.is_scoreboard_frozen(): infos.append("Scoreboard has been frozen") if is_admin() is True and scores_visible() is False: infos.append("Scores are not currently visible to users") standings = get_standings() standings_interne = [s for s in standings if s.fields != True] standings_externe = [s for s in standings if s.fields == True] return render_template("scoreboard.html", standings_interne=standings_interne, standings_externe=standings_externe, infos=infos)
def get(self, user_id): if user_id == 'me': if not authed(): abort(403) user = get_current_user() else: if accounts_visible() is False or scores_visible() is False: abort(404) user = Users.query.filter_by(id=user_id).first_or_404() awards = user.get_awards(admin=is_admin()) view = 'user' if not is_admin() else 'admin' response = AwardSchema(view=view, many=True).dump(awards) if response.errors: return {'success': False, 'errors': response.errors}, 400 return {'success': True, 'data': response.data}
def get(self, user_id): if user_id == 'me': if not authed(): abort(403) user = get_current_user() else: if accounts_visible() is False or scores_visible() is False: abort(404) user = Users.query.filter_by(id=user_id).first_or_404() solves = user.get_solves(admin=is_admin()) for solve in solves: setattr(solve, 'value', 100) view = 'user' if not is_admin() else 'admin' response = SubmissionSchema(view=view, many=True).dump(solves) if response.errors: return {'success': False, 'errors': response.errors}, 400 return {'success': True, 'data': response.data}
def scoreboard_listing(): infos = get_infos() if config.is_scoreboard_frozen(): infos.append("Scoreboard has been frozen") if is_admin() is True and scores_visible() is False: infos.append("Scores are not currently visible to users") Model = get_model() standings = get_standings(fields=[Model.email]) category_standings = get_category_standings() return render_template( "scoreboard.html", standings=standings, category_standings=category_standings, infos=infos, email_group_asset=email_group_asset, )
def get(self, team_id): if team_id == "me": if not authed(): abort(403) team = get_current_team() awards = team.get_awards(admin=True) else: if accounts_visible() is False or scores_visible() is False: abort(404) team = Teams.query.filter_by(id=team_id).first_or_404() if (team.banned or team.hidden) and is_admin() is False: abort(404) awards = team.get_awards(admin=is_admin()) schema = AwardSchema(many=True) response = schema.dump(awards) if response.errors: return {"success": False, "errors": response.errors}, 400 return {"success": True, "data": response.data}
def get(self, user_id): if user_id == "me": if not authed(): abort(403) user = get_current_user() awards = user.get_awards(admin=True) else: if accounts_visible() is False or scores_visible() is False: abort(404) user = Users.query.filter_by(id=user_id).first_or_404() if (user.banned or user.hidden) and is_admin() is False: abort(404) awards = user.get_awards(admin=is_admin()) view = "user" if not is_admin() else "admin" response = AwardSchema(view=view, many=True).dump(awards) if response.errors: return {"success": False, "errors": response.errors}, 400 return {"success": True, "data": response.data}
def get(self, challenge_id): if is_admin(): chal = Challenges.query.filter(Challenges.id == challenge_id).first_or_404() else: chal = Challenges.query.filter( Challenges.id == challenge_id, and_(Challenges.state != "hidden", Challenges.state != "locked"), ).first_or_404() chal_class = get_chal_class(chal.type) if chal.requirements: requirements = chal.requirements.get("prerequisites", []) anonymize = chal.requirements.get("anonymize") if challenges_visible(): user = get_current_user() if user: solve_ids = ( Solves.query.with_entities(Solves.challenge_id) .filter_by(account_id=user.account_id) .order_by(Solves.challenge_id.asc()) .all() ) else: # We need to handle the case where a user is viewing challenges anonymously solve_ids = [] solve_ids = set([value for value, in solve_ids]) prereqs = set(requirements) if solve_ids >= prereqs or is_admin(): pass else: if anonymize: return { "success": True, "data": { "id": chal.id, "type": "hidden", "name": "???", "value": 0, "category": "???", "tags": [], "template": "", "script": "", }, } abort(403) else: abort(403) tags = [ tag["value"] for tag in TagSchema("user", many=True).dump(chal.tags).data ] unlocked_hints = set() hints = [] if authed(): user = get_current_user() team = get_current_team() # TODO: Convert this into a re-useable decorator if is_admin(): pass else: if config.is_teams_mode() and team is None: abort(403) unlocked_hints = set( [ u.target for u in HintUnlocks.query.filter_by( type="hints", account_id=user.account_id ) ] ) files = [] for f in chal.files: token = { "user_id": user.id, "team_id": team.id if team else None, "file_id": f.id, } files.append( url_for("views.files", path=f.location, token=serialize(token)) ) else: files = [url_for("views.files", path=f.location) for f in chal.files] for hint in Hints.query.filter_by(challenge_id=chal.id).all(): if hint.id in unlocked_hints or ctf_ended(): hints.append( {"id": hint.id, "cost": hint.cost, "content": hint.content} ) else: hints.append({"id": hint.id, "cost": hint.cost}) response = chal_class.read(challenge=chal) Model = get_model() if scores_visible() is True and accounts_visible() is True: solves = Solves.query.join(Model, Solves.account_id == Model.id).filter( Solves.challenge_id == chal.id, Model.banned == False, Model.hidden == False, ) # Only show solves that happened before freeze time if configured freeze = get_config("freeze") if not is_admin() and freeze: solves = solves.filter(Solves.date < unix_time_to_utc(freeze)) solves = solves.count() response["solves"] = solves else: response["solves"] = None response["files"] = files response["tags"] = tags response["hints"] = hints db.session.close() return {"success": True, "data": response}
def get(self, challenge_id): if is_admin(): chal = Challenges.query.filter( Challenges.id == challenge_id).first_or_404() else: chal = Challenges.query.filter( Challenges.id == challenge_id, and_(Challenges.state != "hidden", Challenges.state != "locked"), ).first_or_404() try: chal_class = get_chal_class(chal.type) except KeyError: abort( 500, f"The underlying challenge type ({chal.type}) is not installed. This challenge can not be loaded.", ) if chal.requirements: requirements = chal.requirements.get("prerequisites", []) anonymize = chal.requirements.get("anonymize") # Gather all challenge IDs so that we can determine invalid challenge prereqs all_challenge_ids = { c.id for c in Challenges.query.with_entities(Challenges.id).all() } if challenges_visible(): user = get_current_user() if user: solve_ids = (Solves.query.with_entities( Solves.challenge_id).filter_by( account_id=user.account_id).order_by( Solves.challenge_id.asc()).all()) else: # We need to handle the case where a user is viewing challenges anonymously solve_ids = [] solve_ids = {value for value, in solve_ids} prereqs = set(requirements).intersection(all_challenge_ids) if solve_ids >= prereqs or is_admin(): pass else: if anonymize: return { "success": True, "data": { "id": chal.id, "type": "hidden", "name": "???", "value": 0, "solves": None, "solved_by_me": False, "category": "???", "tags": [], "template": "", "script": "", }, } abort(403) else: abort(403) tags = [ tag["value"] for tag in TagSchema("user", many=True).dump(chal.tags).data ] unlocked_hints = set() hints = [] if authed(): user = get_current_user() team = get_current_team() # TODO: Convert this into a re-useable decorator if is_admin(): pass else: if config.is_teams_mode() and team is None: abort(403) unlocked_hints = { u.target for u in HintUnlocks.query.filter_by( type="hints", account_id=user.account_id) } files = [] for f in chal.files: token = { "user_id": user.id, "team_id": team.id if team else None, "file_id": f.id, } files.append( url_for("views.files", path=f.location, token=serialize(token))) else: files = [ url_for("views.files", path=f.location) for f in chal.files ] for hint in Hints.query.filter_by(challenge_id=chal.id).all(): if hint.id in unlocked_hints or ctf_ended(): hints.append({ "id": hint.id, "cost": hint.cost, "content": hint.content }) else: hints.append({"id": hint.id, "cost": hint.cost}) response = chal_class.read(challenge=chal) solves_q, user_solves = _build_solves_query( extra_filters=(Solves.challenge_id == chal.id, )) # If there are no solves for this challenge ID then we have 0 rows maybe_row = solves_q.first() if maybe_row: challenge_id, solve_count = maybe_row solved_by_user = challenge_id in user_solves else: solve_count, solved_by_user = 0, False # Hide solve counts if we are hiding solves/accounts if scores_visible() is False or accounts_visible() is False: solve_count = None if authed(): # Get current attempts for the user attempts = Submissions.query.filter_by( account_id=user.account_id, challenge_id=challenge_id).count() else: attempts = 0 response["solves"] = solve_count response["solved_by_me"] = solved_by_user response["attempts"] = attempts response["files"] = files response["tags"] = tags response["hints"] = hints response["view"] = render_template( chal_class.templates["view"].lstrip("/"), solves=solve_count, solved_by_me=solved_by_user, files=files, tags=tags, hints=[Hints(**h) for h in hints], max_attempts=chal.max_attempts, attempts=attempts, challenge=chal, ) db.session.close() return {"success": True, "data": response}
def get(self, query_args): # Require a team if in teams mode # TODO: Convert this into a re-useable decorator # TODO: The require_team decorator doesnt work because of no admin passthru if get_current_user_attrs(): if is_admin(): pass else: if config.is_teams_mode() and get_current_team_attrs() is None: abort(403) # Build filtering queries q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Challenges, query=q, field=field) # Admins get a shortcut to see all challenges despite pre-requisites admin_view = is_admin() and request.args.get("view") == "admin" solve_counts = {} # Build a query for to show challenge solve information. We only # give an admin view if the request argument has been provided. # # NOTE: This is different behaviour to the challenge detail # endpoint which only needs the current user to be an admin rather # than also also having to provide `view=admin` as a query arg. solves_q, user_solves = _build_solves_query(admin_view=admin_view) # Aggregate the query results into the hashes defined at the top of # this block for later use for chal_id, solve_count in solves_q: solve_counts[chal_id] = solve_count if scores_visible() and accounts_visible(): solve_count_dfl = 0 else: # Empty out the solves_count if we're hiding scores/accounts solve_counts = {} # This is necessary to match the challenge detail API which returns # `None` for the solve count if visiblity checks fail solve_count_dfl = None # Build the query for the challenges which may be listed chal_q = Challenges.query # Admins can see hidden and locked challenges in the admin view if admin_view is False: chal_q = chal_q.filter( and_(Challenges.state != "hidden", Challenges.state != "locked")) chal_q = (chal_q.filter_by(**query_args).filter(*filters).order_by( Challenges.value, Challenges.id)) # Iterate through the list of challenges, adding to the object which # will be JSONified back to the client response = [] tag_schema = TagSchema(view="user", many=True) # Gather all challenge IDs so that we can determine invalid challenge prereqs all_challenge_ids = { c.id for c in Challenges.query.with_entities(Challenges.id).all() } for challenge in chal_q: if challenge.requirements: requirements = challenge.requirements.get("prerequisites", []) anonymize = challenge.requirements.get("anonymize") prereqs = set(requirements).intersection(all_challenge_ids) if user_solves >= prereqs or admin_view: pass else: if anonymize: response.append({ "id": challenge.id, "type": "hidden", "name": "???", "value": 0, "solves": None, "solved_by_me": False, "category": "???", "tags": [], "template": "", "script": "", }) # Fallthrough to continue continue try: challenge_type = get_chal_class(challenge.type) except KeyError: # Challenge type does not exist. Fall through to next challenge. continue # Challenge passes all checks, add it to response response.append({ "id": challenge.id, "type": challenge_type.name, "name": challenge.name, "value": challenge.value, "solves": solve_counts.get(challenge.id, solve_count_dfl), "solved_by_me": challenge.id in user_solves, "category": challenge.category, "tags": tag_schema.dump(challenge.tags).data, "template": challenge_type.templates["view"], "script": challenge_type.scripts["view"], }) db.session.close() return {"success": True, "data": response}
def get(self, challenge_id): if is_admin(): chal = Challenges.query.filter( Challenges.id == challenge_id).first_or_404() else: chal = Challenges.query.filter( Challenges.id == challenge_id, and_(Challenges.state != 'hidden', Challenges.state != 'locked')).first_or_404() chal_class = get_chal_class(chal.type) if chal.requirements: requirements = chal.requirements.get('prerequisites', []) anonymize = chal.requirements.get('anonymize') if challenges_visible(): user = get_current_user() if user: solve_ids = Solves.query \ .with_entities(Solves.challenge_id) \ .filter_by(account_id=user.account_id) \ .order_by(Solves.challenge_id.asc()) \ .all() else: # We need to handle the case where a user is viewing challenges anonymously solve_ids = [] solve_ids = set([value for value, in solve_ids]) prereqs = set(requirements) if solve_ids >= prereqs or is_admin(): pass else: if anonymize: return { 'success': True, 'data': { 'id': chal.id, 'type': 'hidden', 'name': '???', 'value': 0, 'category': '???', 'tags': [], 'template': '', 'script': '' } } abort(403) else: abort(403) tags = [ tag['value'] for tag in TagSchema("user", many=True).dump(chal.tags).data ] files = [f.location for f in chal.files] unlocked_hints = set() hints = [] if authed(): user = get_current_user() unlocked_hints = set([ u.target for u in HintUnlocks.query.filter_by( type='hints', account_id=user.account_id) ]) for hint in Hints.query.filter_by(challenge_id=chal.id).all(): if hint.id in unlocked_hints or ctf_ended(): hints.append({ 'id': hint.id, 'cost': hint.cost, 'content': hint.content }) else: hints.append({'id': hint.id, 'cost': hint.cost}) response = chal_class.read(challenge=chal) Model = get_model() if scores_visible() is True and accounts_visible() is True: solves = Solves.query\ .join(Model, Solves.account_id == Model.id)\ .filter(Solves.challenge_id == chal.id, Model.banned == False, Model.hidden == False)\ .count() response['solves'] = solves else: response['solves'] = None response['files'] = files response['tags'] = tags response['hints'] = hints db.session.close() return {'success': True, 'data': response}