def delete(self, user_id): # Admins should not be able to delete themselves if user_id == session["id"]: return ( { "success": False, "errors": { "id": "You cannot delete yourself" } }, 400, ) Notifications.query.filter_by(user_id=user_id).delete() Awards.query.filter_by(user_id=user_id).delete() Unlocks.query.filter_by(user_id=user_id).delete() Submissions.query.filter_by(user_id=user_id).delete() Solves.query.filter_by(user_id=user_id).delete() Tracking.query.filter_by(user_id=user_id).delete() Users.query.filter_by(id=user_id).delete() db.session.commit() db.session.close() clear_user_session(user_id=user_id) clear_standings() return {"success": True}
def patch(self, user_id): user = Users.query.filter_by(id=user_id).first_or_404() data = request.get_json() data["id"] = user_id # Admins should not be able to ban themselves if data["id"] == session["id"] and (data.get("banned") is True or data.get("banned") == "true"): return ( { "success": False, "errors": { "id": "You cannot ban yourself" } }, 400, ) schema = UserSchema(view="admin", instance=user, partial=True) response = schema.load(data) if response.errors: return {"success": False, "errors": response.errors}, 400 # This generates the response first before actually changing the type # This avoids an error during User type changes where we change # the polymorphic identity resulting in an ObjectDeletedError # https://github.com/CTFd/CTFd/issues/1794 response = schema.dump(response.data) db.session.commit() db.session.close() clear_user_session(user_id=user_id) clear_standings() return {"success": True, "data": response.data}
def gen_award(db, user_id, team_id=None, name="award_name", value=100): award = Awards(user_id=user_id, team_id=team_id, name=name, value=value) award.date = datetime.datetime.utcnow() db.session.add(award) db.session.commit() clear_standings() return award
def post(self): req = request.get_json() user = get_current_user() req["user_id"] = user.id req["team_id"] = user.team_id Model = get_class_by_tablename(req["type"]) target = Model.query.filter_by(id=req["target"]).first_or_404() if target.cost > user.score: return ( { "success": False, "errors": { "score": "You do not have enough points to unlock this hint" }, }, 400, ) schema = UnlockSchema() response = schema.load(req, session=db.session) if response.errors: return {"success": False, "errors": response.errors}, 400 existing = Unlocks.query.filter_by(**req).first() if existing: return ( { "success": False, "errors": { "target": "You've already unlocked this this target" }, }, 400, ) db.session.add(response.data) award_schema = AwardSchema() award = { "user_id": user.id, "team_id": user.team_id, "name": target.name, "description": target.description, "value": (-target.cost), "category": target.category, } award = award_schema.load(award) db.session.add(award.data) db.session.commit() clear_standings() response = schema.dump(response.data) return {"success": True, "data": response.data}
def patch(self, user_id): user = Users.query.filter_by(id=user_id).first_or_404() data = request.get_json() data["id"] = user_id # Admins should not be able to ban themselves if data["id"] == session["id"] and (data.get("banned") is True or data.get("banned") == "true"): return ( { "success": False, "errors": { "id": "You cannot ban yourself" } }, 400, ) schema = UserSchema(view="admin", instance=user, partial=True) response = schema.load(data) if response.errors: return {"success": False, "errors": response.errors}, 400 db.session.commit() response = schema.dump(response.data) db.session.close() clear_user_session(user_id=user_id) clear_standings() return {"success": True, "data": response}
def truncate_database(): # delete all table data (but keep tables) _pages = Pages.query.all() for p in _pages: for f in p.files: delete_file(file_id=f.id) Pages.query.delete() Notifications.query.delete() _challenges = Challenges.query.all() for c in _challenges: for f in c.files: delete_file(file_id=f.id) Challenges.query.delete() Users.query.delete() Teams.query.delete() Solves.query.delete() Submissions.query.delete() Awards.query.delete() Unlocks.query.delete() Tracking.query.delete() Configs.query.delete() clear_config() clear_pages() clear_standings() cache.clear() db.session.commit()
def post(self): req = request.get_json() user = get_current_user() req["user_id"] = user.id req["team_id"] = user.team_id Model = get_class_by_tablename(req["type"]) target = Model.query.filter_by(id=req["target"]).first_or_404() if target.cost > user.score: return ( { "success": False, "errors": { "score": "У вас недостаточно очков, чтобы разблокировать эту подсказку" }, }, 400, ) schema = UnlockSchema() response = schema.load(req, session=db.session) if response.errors: return {"success": False, "errors": response.errors}, 400 existing = Unlocks.query.filter_by(**req).first() if existing: return ( { "success": False, "errors": { "target": "Вы уже разблокировали это" }, }, 400, ) db.session.add(response.data) award_schema = AwardSchema() award = { "user_id": user.id, "team_id": user.team_id, "name": target.name, "description": target.description, "value": (-target.cost), "category": target.category, } award = award_schema.load(award) db.session.add(award.data) db.session.commit() clear_standings() response = schema.dump(response.data) return {"success": True, "data": response.data}
def test_scoreboard_is_cached(): """Test that /api/v1/scoreboard is properly cached and cleared""" app = create_ctfd() with app.app_context(): # create user1 register_user(app, name="user1", email="*****@*****.**") # create challenge chal = gen_challenge(app.db, value=100) gen_flag(app.db, challenge_id=chal.id, content="flag") chal_id = chal.id # create a solve for the challenge for user1. (the id is 2 because of the admin) gen_solve(app.db, user_id=2, challenge_id=chal_id) with login_as_user(app, "user1") as client: # No cached data assert app.cache.get("view/api.scoreboard_scoreboard_list") is None assert app.cache.get( "view/api.scoreboard_scoreboard_detail") is None # Load and check cached data client.get("/api/v1/scoreboard") assert app.cache.get("view/api.scoreboard_scoreboard_list") client.get("/api/v1/scoreboard/top/10") assert app.cache.get("view/api.scoreboard_scoreboard_detail") # Empty standings and check that the cached data is gone clear_standings() assert app.cache.get("view/api.scoreboard_scoreboard_list") is None assert app.cache.get( "view/api.scoreboard_scoreboard_detail") is None destroy_ctfd(app)
def patch(self, config_key): config = Configs.query.filter_by(key=config_key).first() data = request.get_json() if config: schema = ConfigSchema(instance=config, partial=True) response = schema.load(data) else: schema = ConfigSchema() data['key'] = config_key response = schema.load(data) db.session.add(response.data) if response.errors: return response.errors, 400 db.session.commit() response = schema.dump(response.data) db.session.close() clear_config() clear_standings() return { 'success': True, 'data': response.data }
def delete(self): team_disbanding = get_config("team_disbanding", default="inactive_only") if team_disbanding == "disabled": return ( { "success": False, "errors": {"": ["Team disbanding is currently disabled"]}, }, 403, ) team = get_current_team() if team.captain_id != session["id"]: return ( { "success": False, "errors": {"": ["Only team captains can disband their team"]}, }, 403, ) # The team must not have performed any actions in the CTF performed_actions = any( [ team.solves != [], team.fails != [], team.awards != [], Submissions.query.filter_by(team_id=team.id).all() != [], Unlocks.query.filter_by(team_id=team.id).all() != [], ] ) if performed_actions: return ( { "success": False, "errors": { "": [ "You cannot disband your team as it has participated in the event. " "Please contact an admin to disband your team or remove a member." ] }, }, 403, ) for member in team.members: member.team_id = None clear_user_session(user_id=member.id) db.session.delete(team) db.session.commit() clear_team_session(team_id=team.id) clear_standings() db.session.close() return {"success": True}
def reset(): if request.method == "POST": require_setup = False logout = False next_url = url_for("admin.statistics") data = request.form if data.get("pages"): _pages = Pages.query.all() for p in _pages: for f in p.files: delete_file(file_id=f.id) Pages.query.delete() if data.get("notifications"): Notifications.query.delete() if data.get("challenges"): _challenges = Challenges.query.all() for c in _challenges: for f in c.files: delete_file(file_id=f.id) Challenges.query.delete() if data.get("accounts"): Users.query.delete() Teams.query.delete() require_setup = True logout = True if data.get("submissions"): Solves.query.delete() Submissions.query.delete() Awards.query.delete() Unlocks.query.delete() Tracking.query.delete() if require_setup: set_config("setup", False) cache.clear() logout_user() next_url = url_for("views.setup") db.session.commit() clear_pages() clear_standings() clear_config() if logout is True: cache.clear() logout_user() db.session.close() return redirect(next_url) return render_template("admin/reset.html")
def delete(self, award_id): award = Awards.query.filter_by(id=award_id).first_or_404() db.session.delete(award) db.session.commit() db.session.close() # Delete standings cache because awards can change scores clear_standings() return {"success": True}
def patch(self): req = request.get_json() for key, value in req.items(): set_config(key=key, value=value) clear_config() clear_standings() return {"success": True}
def attempt_single(self, request, request_data, user, team, kpm, challenge): challenge_id = challenge.id if challenge.state == "hidden": return False, '' if challenge.state == "locked": return False, '' if challenge.requirements: requirements = challenge.requirements.get("prerequisites", []) 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([solve_id for solve_id, in solve_ids]) prereqs = set(requirements) if solve_ids >= prereqs: pass else: return False, '' chal_class = get_chal_class(challenge.type) solves = Solves.query.filter_by(account_id=user.account_id, challenge_id=challenge_id).first() # Challenge not solved yet if not solves: status, message = chal_class.attempt(challenge, request) if status: # The challenge plugin says the input is right if ctftime() or current_user.is_admin(): chal_class.solve(user=user, team=team, challenge=challenge, request=request) clear_standings() log( "submissions", "[{date}] {name} submitted {submission} with kpm {kpm} [CORRECT]", submission=request_data["submission"].encode("utf-8"), kpm=kpm, ) return True, message else: # The challenge plugin says the input is wrong if ctftime() or current_user.is_admin(): clear_standings() return False, message # Challenge already solved else: return False, ''
def delete(self, submission_id): submission = Submissions.query.filter_by( id=submission_id).first_or_404() db.session.delete(submission) db.session.commit() db.session.close() # Delete standings cache clear_standings() return {"success": True}
def delete(self, config_key): config = Configs.query.filter_by(key=config_key).first_or_404() db.session.delete(config) db.session.commit() db.session.close() clear_config() clear_standings() return {"success": True}
def delete(self, team_id): team = Teams.query.filter_by(id=team_id).first_or_404() for member in team.members: member.team_id = None db.session.delete(team) db.session.commit() db.session.close() clear_standings() return {"success": True}
def delete(self, user_id): Notifications.query.filter_by(user_id=user_id).delete() Awards.query.filter_by(user_id=user_id).delete() Unlocks.query.filter_by(user_id=user_id).delete() Submissions.query.filter_by(user_id=user_id).delete() Solves.query.filter_by(user_id=user_id).delete() Tracking.query.filter_by(user_id=user_id).delete() Users.query.filter_by(id=user_id).delete() db.session.commit() db.session.close() clear_standings() return {"success": True}
def patch(self): req = request.get_json() schema = ConfigSchema() for key, value in req.items(): response = schema.load({"key": key, "value": value}) if response.errors: return {"success": False, "errors": response.errors}, 400 set_config(key=key, value=value) clear_config() clear_standings() return {"success": True}
def patch(self): user = get_current_user() data = request.get_json() schema = UserSchema(view="self", instance=user, partial=True) response = schema.load(data) if response.errors: return {"success": False, "errors": response.errors}, 400 db.session.commit() response = schema.dump(response.data) db.session.close() clear_standings() return {"success": True, "data": response.data}
def post(self): req = request.get_json() schema = UserSchema('admin') response = schema.load(req) if response.errors: return {'success': False, 'errors': response.errors}, 400 db.session.add(response.data) db.session.commit() clear_standings() response = schema.dump(response.data) return {'success': True, 'data': response.data}
def post(self): req = request.get_json() Model = Submissions.get_child(type=req.get("type")) schema = SubmissionSchema(instance=Model()) response = schema.load(req) 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() # Delete standings cache clear_standings() return {"success": True, "data": response.data}
def delete(self, user_id): # import time; time.sleep(60) if get_current_user().id == user_id: return {'success': False, 'data': 'Cannot delete own account'} Notifications.query.filter_by(user_id=user_id).delete() Awards.query.filter_by(user_id=user_id).delete() Unlocks.query.filter_by(user_id=user_id).delete() Submissions.query.filter_by(user_id=user_id).delete() Solves.query.filter_by(user_id=user_id).delete() Tracking.query.filter_by(user_id=user_id).delete() Users.query.filter_by(id=user_id).delete() db.session.commit() db.session.close() clear_standings() return {"success": True}
def gen_solve(db, user_id, team_id=None, challenge_id=None, ip="127.0.0.1", provided="rightkey", **kwargs): solve = Solves(user_id=user_id, team_id=team_id, challenge_id=challenge_id, ip=ip, provided=provided, **kwargs) solve.date = datetime.datetime.utcnow() db.session.add(solve) db.session.commit() clear_standings() return solve
def post(self): req = request.get_json() schema = AwardSchema() 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() # Delete standings cache because awards can change scores clear_standings() return {"success": True, "data": response.data}
def post(self): req = request.get_json() schema = ConfigSchema() response = schema.load(req) 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() clear_config() clear_standings() return {"success": True, "data": response.data}
def patch(self, team_id): team = Teams.query.filter_by(id=team_id).first_or_404() data = request.get_json() data["id"] = team_id schema = TeamSchema(view="admin", instance=team, partial=True) response = schema.load(data) if response.errors: return {"success": False, "errors": response.errors}, 400 response = schema.dump(response.data) db.session.commit() db.session.close() clear_standings() return {"success": True, "data": response.data}
def post(self): req = request.get_json() view = TeamSchema.views.get(session.get("type", "self")) schema = TeamSchema(view=view) response = schema.load(req) 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() clear_standings() return {"success": True, "data": response.data}
def post(self): req = request.get_json() view = TeamSchema.views.get(session.get('type', 'self')) schema = TeamSchema(view=view) response = schema.load(req) 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() clear_standings() return {'success': True, 'data': response.data}
def patch(self): req = request.get_json() schema = ConfigSchema() for key, value in req.items(): response = schema.load({"key": key, "value": value}) if response.errors: # Inject config key into error config_key = response.data["key"] response.errors["value"][ 0] = f"{config_key} config is too long" return {"success": False, "errors": response.errors}, 400 set_config(key=key, value=value) clear_config() clear_standings() return {"success": True}