Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
 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())
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
    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}}
Exemplo n.º 6
0
    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}}
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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}}
Exemplo n.º 9
0
    def place(self):
        from CTFd.utils.config.visibility import scores_visible

        if scores_visible():
            return self.get_place(admin=False)
        else:
            return None
Exemplo n.º 10
0
    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
        }
Exemplo n.º 11
0
    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
        }
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
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)
Exemplo n.º 15
0
    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
        }
Exemplo n.º 16
0
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)
Exemplo n.º 17
0
    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}
Exemplo n.º 18
0
    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}
Exemplo n.º 19
0
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,
    )
Exemplo n.º 20
0
    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}
Exemplo n.º 21
0
    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}
Exemplo n.º 22
0
    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}
Exemplo n.º 23
0
    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}
Exemplo n.º 24
0
    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}
Exemplo n.º 25
0
    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}