def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Users, query=q, field=field) if is_admin() and request.args.get("view") == "admin": users = (Users.query.filter_by(**query_args).filter( *filters).paginate(per_page=50, max_per_page=100)) else: users = (Users.query.filter_by( banned=False, hidden=False, **query_args).filter(*filters).paginate(per_page=50, max_per_page=100)) response = UserSchema(view="user", many=True).dump(users.items) if response.errors: return {"success": False, "errors": response.errors}, 400 return { "meta": { "pagination": { "page": users.page, "next": users.next_num, "prev": users.prev_num, "pages": users.pages, "per_page": users.per_page, "total": users.total, } }, "success": True, "data": response.data, }
def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Submissions, query=q, field=field) args = query_args schema = SubmissionSchema(many=True) submissions = (Submissions.query.filter_by(**args).filter( *filters).paginate(max_per_page=100)) response = schema.dump(submissions.items) if response.errors: return {"success": False, "errors": response.errors}, 400 return { "meta": { "pagination": { "page": submissions.page, "next": submissions.next_num, "prev": submissions.prev_num, "pages": submissions.pages, "per_page": submissions.per_page, "total": submissions.total, } }, "success": True, "data": response.data, }
def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) CommentModel = get_comment_model(data=query_args) filters = build_model_filters(model=CommentModel, query=q, field=field) comments = (CommentModel.query.filter_by(**query_args).filter( *filters).order_by( CommentModel.id.desc()).paginate(max_per_page=100)) schema = CommentSchema(many=True) response = schema.dump(comments.items) if response.errors: return {"success": False, "errors": response.errors}, 400 return { "meta": { "pagination": { "page": comments.page, "next": comments.next_num, "prev": comments.prev_num, "pages": comments.pages, "per_page": comments.per_page, "total": comments.total, } }, "success": True, "data": response.data, }
def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Configs, query=q, field=field) configs = Configs.query.filter_by(**query_args).filter(*filters).all() schema = ConfigSchema(many=True) response = schema.dump(configs) if response.errors: return {"success": False, "errors": response.errors}, 400 return {"success": True, "data": response.data}
def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Hints, query=q, field=field) hints = Hints.query.filter_by(**query_args).filter(*filters).all() response = HintSchema(many=True, view="locked").dump(hints) if response.errors: return {"success": False, "errors": response.errors}, 400 return {"success": True, "data": response.data}
def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Pages, query=q, field=field) pages = Pages.query.filter_by(**query_args).filter(*filters).all() schema = PageSchema(exclude=["content"], many=True) response = schema.dump(pages) if response.errors: return {"success": False, "errors": response.errors}, 400 return {"success": True, "data": response.data}
def submissions_listing(submission_type): filters_by = {} if submission_type: filters_by["type"] = submission_type filters = [] q = request.args.get("q") field = request.args.get("field") page = abs(request.args.get("page", 1, type=int)) filters = build_model_filters( model=Submissions, query=q, field=field, extra_columns={ "challenge_name": Challenges.name, "account_id": Submissions.account_id, }, ) Model = get_model() submissions = ( Submissions.query.filter_by(**filters_by) .filter(*filters) .join(Challenges) .join(Model) .order_by(Submissions.date.desc()) .paginate(page=page, per_page=50) ) args = dict(request.args) args.pop("page", 1) return render_template( "admin/submissions.html", submissions=submissions, prev_page=url_for( request.endpoint, submission_type=submission_type, page=submissions.prev_num, **args ), next_page=url_for( request.endpoint, submission_type=submission_type, page=submissions.next_num, **args ), type=submission_type, q=q, field=field, )
def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Notifications, query=q, field=field) notifications = (Notifications.query.filter_by(**query_args).filter( *filters).all()) schema = NotificationSchema(many=True) result = schema.dump(notifications) if result.errors: return {"success": False, "errors": result.errors}, 400 return {"success": True, "data": result.data}
def get(self, query_args): q = query_args.pop("q", None) field = str(query_args.pop("field", None)) filters = build_model_filters(model=Teams, query=q, field=field) if is_admin() and request.args.get("view") == "admin": teams = ( Teams.query.filter_by(**query_args) .filter(*filters) .paginate(per_page=50, max_per_page=100) ) else: teams = ( Teams.query.filter_by(hidden=False, banned=False, **query_args) .filter(*filters) .paginate(per_page=50, max_per_page=100) ) user_type = get_current_user_type(fallback="user") view = copy.deepcopy(TeamSchema.views.get(user_type)) view.remove("members") response = TeamSchema(view=view, many=True).dump(teams.items) if response.errors: return {"success": False, "errors": response.errors}, 400 return { "meta": { "pagination": { "page": teams.page, "next": teams.next_num, "prev": teams.prev_num, "pages": teams.pages, "per_page": teams.per_page, "total": teams.total, } }, "success": True, "data": response.data, }
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, 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() # Reorder response # TODO: Able to set arbitrary total ordering # For now just set the ones matching config.top_category to the front # JS will put categories in order of first appearance at top response.sort(key= lambda x: x["category"] == get_config("top_category")) return {"success": True, "data": response}