Ejemplo n.º 1
0
    def get(self):
        # This can return None (unauth) if visibility is set to public
        user = get_current_user()

        challenges = (Challenges.query.filter(
            and_(Challenges.state != "hidden",
                 Challenges.state != "locked")).order_by(
                     Challenges.value).all())

        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())

            if is_admin():
                pass
            else:
                if config.is_teams_mode() and get_current_team() is None:
                    abort(403)
        else:
            solve_ids = []

        response = []
        tag_schema = TagSchema(view="user", many=True)
        for challenge in challenges:
            if challenge.requirements:
                requirements = challenge.requirements.get("prerequisites", [])
                anonymize = challenge.requirements.get("anonymize")
                if compare(requirements, solve_ids):
                    pass
                else:
                    if anonymize:
                        response.append({
                            "id": challenge.id,
                            "type": "hidden",
                            "name": "???",
                            "value": 0,
                            "category": "???",
                            "tags": [],
                            "template": "",
                            "script": "",
                        })
                    # Fallthrough to continue
                    continue

            challenge_type = get_chal_class(challenge.type)
            response.append({
                "id": challenge.id,
                "type": challenge_type.name,
                "name": challenge.name,
                "value": challenge.value,
                "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}
Ejemplo n.º 2
0
 def get(self, level_id):
     challenges = (Challenges.query.filter(
         Challenges.level == level_id)).all()
     response = []
     tag_schema = TagSchema(view="user", many=True)
     comp_schema = CompetenceSchema(view="user", many=True)
     for challenge in challenges:
         challenge_type = get_chal_class(challenge.type)
         response.append({
             "id":
             challenge.id,
             "type":
             challenge_type.name,
             "name":
             challenge.name,
             "value":
             challenge.value,
             "category":
             challenge.category,
             "result":
             challenge.result,
             "level":
             challenge.level,
             "tags":
             tag_schema.dump(challenge.tags).data,
             "competences":
             comp_schema.dump(challenge.competences).data,
             "template":
             challenge_type.templates["view"],
             "script":
             challenge_type.scripts["view"],
         })
     db.session.close()
     return {"success": True, "data": response}
Ejemplo n.º 3
0
    def get(self):
        # This can return None (unauth) if visibility is set to public
        user = get_current_user()

        challenges = Challenges.query.filter(
            and_(Challenges.state != 'hidden', Challenges.state != 'locked')
        ).order_by(Challenges.value).all()

        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()
            solve_ids = set([value for value, in solve_ids])
        else:
            solve_ids = set()

        response = []
        tag_schema = TagSchema(view='user', many=True)
        for challenge in challenges:
            if challenge.requirements:
                requirements = challenge.requirements.get('prerequisites', [])
                anonymize = challenge.requirements.get('anonymize')
                prereqs = set(requirements)
                if solve_ids >= prereqs:
                    pass
                else:
                    if anonymize:
                        response.append({
                            'id': challenge.id,
                            'type': 'hidden',
                            'name': '???',
                            'value': 0,
                            'category': '???',
                            'tags': [],
                            'template': '',
                            'script': ''
                        })
                    # Fallthrough to continue
                    continue

            challenge_type = get_chal_class(challenge.type)
            response.append({
                'id': challenge.id,
                'type': challenge_type.name,
                'name': challenge.name,
                'value': challenge.value,
                '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
        }
Ejemplo n.º 4
0
    def get(self):
        # TODO: Filter by challenge_id
        tags = Tags.query.all()
        schema = TagSchema(many=True)
        response = schema.dump(tags)

        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        return {"success": True, "data": response.data}
Ejemplo n.º 5
0
    def get(self, query_args):
        q = query_args.pop("q", None)
        field = str(query_args.pop("field", None))
        filters = build_model_filters(model=Tags, query=q, field=field)

        tags = Tags.query.filter_by(**query_args).filter(*filters).all()
        schema = TagSchema(many=True)
        response = schema.dump(tags)

        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        return {"success": True, "data": response.data}
Ejemplo n.º 6
0
    def patch(self, tag_id):
        tag = Tags.query.filter_by(id=tag_id).first_or_404()
        schema = TagSchema()
        req = request.get_json()

        response = schema.load(req, session=db.session, instance=tag)
        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        db.session.commit()

        response = schema.dump(response.data)
        db.session.close()

        return {"success": True, "data": response.data}
Ejemplo n.º 7
0
    def post(self):
        req = request.get_json()
        schema = TagSchema()
        response = schema.load(req, session=db.session)

        if response.errors:
            return {"success": False, "errors": response.errors}, 400

        db.session.add(response.data)
        db.session.commit()

        response = schema.dump(response.data)
        db.session.close()

        return {"success": True, "data": response.data}
Ejemplo n.º 8
0
    def get(self, skill_id):
        skills = (Competences.query.filter(Competences.id == skill_id)).all()
        schema = ChallengeSchema(only=["id"], many=True)
        for skill in skills:
            data = schema.dump(skill.challenge_id).data
            chall_ids = []
            for chall in data:
                chall_ids += chall.values()

        challenges = (Challenges.query.filter(
            Challenges.id.in_(chall_ids))).all()
        log("debug", "{date} - {data} ", data=challenges)
        tag_schema = TagSchema(view="user", many=True)
        comp_schema = CompetenceSchema(view="user", many=True)
        response = []
        for challenge in challenges:
            challenge_type = get_chal_class(challenge.type)
            response.append({
                "id":
                challenge.id,
                "type":
                challenge_type.name,
                "name":
                challenge.name,
                "value":
                challenge.value,
                "result":
                challenge.result,
                "category":
                challenge.category,
                "level":
                challenge.level,
                "tags":
                tag_schema.dump(challenge.tags).data,
                "competences":
                comp_schema.dump(challenge.competences).data,
                "template":
                challenge_type.templates["view"],
                "script":
                challenge_type.scripts["view"],
            })
        db.session.close()
        return {"success": True, "data": response}
Ejemplo n.º 9
0
    def get(self, query_args):
        # 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)

        # This can return None (unauth) if visibility is set to public
        user = get_current_user()

        # Admins can request to see everything
        if is_admin() and request.args.get("view") == "admin":
            challenges = (Challenges.query.filter_by(**query_args).filter(
                *filters).order_by(Challenges.value).all())
            solve_ids = set([challenge.id for challenge in challenges])
        else:
            challenges = (Challenges.query.filter(
                and_(Challenges.state != "hidden",
                     Challenges.state != "locked")).filter_by(
                         **query_args).filter(*filters).order_by(
                             Challenges.value).all())

            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())
                solve_ids = set([value for value, in solve_ids])

                # TODO: Convert this into a re-useable decorator
                if is_admin():
                    pass
                else:
                    if config.is_teams_mode() and get_current_team() is None:
                        abort(403)
            else:
                solve_ids = set()

        response = []
        tag_schema = TagSchema(view="user", many=True)
        for challenge in challenges:
            if challenge.requirements:
                requirements = challenge.requirements.get("prerequisites", [])
                anonymize = challenge.requirements.get("anonymize")
                prereqs = set(requirements)
                if solve_ids >= prereqs:
                    pass
                else:
                    if anonymize:
                        response.append({
                            "id": challenge.id,
                            "type": "hidden",
                            "name": "???",
                            "value": 0,
                            "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,
                "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}
Ejemplo n.º 10
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}
Ejemplo n.º 11
0
    def get(self):
        challenges = Challenges.query.order_by(Challenges.category,
                                               Challenges.value)
        chal_matrix = [[0] for j in range(50)]

        i = 0
        current_category = False

        for ch in challenges:
            if not current_category or ch.category != current_category:
                current_category = ch.category
                i += 1

            chal_matrix[i].append(ch.id)

        # This can return None (unauth) if visibility is set to public
        user = get_current_user()

        challenges = (Challenges.query.filter(
            and_(Challenges.state != "hidden",
                 Challenges.state != "locked")).order_by(
                     Challenges.category.desc(), Challenges.value).all())

        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())
            solve_ids = set([value for value, in solve_ids])

            # TODO: Convert this into a re-useable decorator
            if is_admin():
                pass
            else:
                if config.is_teams_mode() and get_current_team() is None:
                    abort(403)
        else:
            solve_ids = set()

        response = []
        tag_schema = TagSchema(view="user", many=True)
        for challenge in challenges:
            challenge_is_open = type(
                chal_is_available(challenge.id, chal_matrix,
                                  solve_ids)) != dict
            if challenge.requirements:
                requirements = challenge.requirements.get("prerequisites", [])
                anonymize = challenge.requirements.get("anonymize")
                prereqs = set(requirements)
                if solve_ids >= prereqs:
                    pass
                else:
                    if anonymize:
                        response.append({
                            "id": challenge.id,
                            "type": "hidden",
                            "name": "???",
                            "value": 0,
                            "category": "???",
                            "tags": [],
                            "template": "",
                            "script": "",
                        })
                    # Fallthrough to continue
                    continue

            challenge_type = get_chal_class(challenge.type)
            response.append({
                "id": challenge.id,
                "type": challenge_type.name,
                "name": challenge.name,
                "value": challenge.value,
                "category": challenge.category,
                "tags": tag_schema.dump(challenge.tags).data,
                "template": challenge_type.templates["view"],
                "script": challenge_type.scripts["view"],
                "open": challenge_is_open,
                "grade": challenge.grade
            })

        db.session.close()
        return {"success": True, "data": response}