def get(self, user_id): 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, team_id): 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, team_id): team = Teams.query.filter_by(id=team_id).first_or_404() if (team.banned or team.hidden) and is_admin() is False: abort(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 get(self): user = get_current_user() fails = user.get_fails(admin=True) 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 validate_captain_id(self, data): captain_id = data.get("captain_id") if captain_id is None: return if is_admin(): team_id = data.get("id") if team_id: target_team = Teams.query.filter_by(id=team_id).first() else: target_team = get_current_team() captain = Users.query.filter_by(id=captain_id).first() if captain in target_team.members: return else: raise ValidationError("Invalid Captain ID", field_names=["captain_id"]) else: current_team = get_current_team() current_user = get_current_user() if current_team.captain_id == current_user.id: return else: raise ValidationError( "Only the captain can change team captain", field_names=["captain_id"], )
def validate_password_confirmation(self, data): password = data.get("password") confirm = data.get("confirm") if is_admin(): pass else: current_team = get_current_team() current_user = get_current_user() if current_team.captain_id != current_user.id: raise ValidationError( "Only the captain can change the team password", field_names=["captain_id"], ) if password and (bool(confirm) is False): raise ValidationError( "Please confirm your current password", field_names=["confirm"] ) if password and confirm: test = verify_password( plaintext=confirm, ciphertext=current_team.password ) if test is True: return data else: raise ValidationError( "Your previous password is incorrect", field_names=["confirm"] ) else: data.pop("password", None) data.pop("confirm", None)
def integrations(): if is_admin() or is_setup() is False: name = request.values.get("name") state = request.values.get("state") try: state = unserialize(state, max_age=3600) except (BadSignature, BadTimeSignature): state = False except Exception: state = False if state: if name == "mlc": mlc_client_id = request.values.get("mlc_client_id") mlc_client_secret = request.values.get("mlc_client_secret") set_config("oauth_client_id", mlc_client_id) set_config("oauth_client_secret", mlc_client_secret) return render_template("admin/integrations.html") else: abort(404) else: abort(403) else: abort(403)
def _check_score_visibility(*args, **kwargs): v = get_config("score_visibility") if v == "public": return f(*args, **kwargs) elif v == "private": if authed(): return f(*args, **kwargs) else: if request.content_type == "application/json": abort(403) else: return redirect( url_for("auth.login", next=request.full_path)) elif v == "hidden": return ( render_template("errors/403.html", error="Scores are currently hidden"), 403, ) elif v == "admins": if is_admin(): return f(*args, **kwargs) else: abort(404)
def post(self, team_id): team = Teams.query.filter_by(id=team_id).first_or_404() data = request.get_json() user_id = data["user_id"] user = Users.query.filter_by(id=user_id).first_or_404() if user.team_id is None: team.members.append(user) db.session.commit() else: return ( { "success": False, "errors": { "id": ["User has already joined a team"] }, }, 400, ) view = "admin" if is_admin() else "user" schema = TeamSchema(view=view) response = schema.dump(team) if response.errors: return {"success": False, "errors": response.errors}, 400 members = response.data.get("members") return {"success": True, "data": members}
def unique_email(email, model=Users): obj = model.query.filter_by(email=email).first() if is_admin(): if obj: raise ValidationError("Email address has already been used") if obj and obj.id != get_current_user().id: raise ValidationError("Email address has already been used")
def validate_email(self, data): email = data.get("email") if email is None: return existing_team = Teams.query.filter_by(email=email).first() if is_admin(): team_id = data.get("id") if team_id: if existing_team and existing_team.id != team_id: raise ValidationError( "Email address has already been used", field_names=["email"] ) else: if existing_team: raise ValidationError( "Email address has already been used", field_names=["email"] ) else: current_team = get_current_team() if email == current_team.email: return data else: if existing_team: raise ValidationError( "Email address has already been used", field_names=["email"] )
def challenges_visible(): v = get_config("challenge_visibility") if v == "public": return True elif v == "private": return authed() elif v == "admins": return is_admin()
def admins_only_wrapper(*args, **kwargs): if is_admin(): return f(*args, **kwargs) else: if request.content_type == "application/json": abort(403) else: return redirect(url_for("auth.login", next=request.full_path))
def accounts_visible(): v = get_config("account_visibility") if v == "public": return True elif v == "private": return authed() elif v == "admins": return is_admin()
def validate_email(self, data): email = data.get("email") if email is None: return email = email.strip() existing_user = Users.query.filter_by(email=email).first() current_user = get_current_user() if is_admin(): user_id = data.get("id") if user_id: if existing_user and existing_user.id != user_id: raise ValidationError( "Email address has already been used", field_names=["email"]) else: if existing_user: if current_user: if current_user.id != existing_user.id: raise ValidationError( "Email address has already been used", field_names=["email"], ) else: raise ValidationError( "Email address has already been used", field_names=["email"]) else: if email == current_user.email: return data else: confirm = data.get("confirm") if bool(confirm) is False: raise ValidationError( "Please confirm your current password", field_names=["confirm"]) test = verify_password(plaintext=confirm, ciphertext=current_user.password) if test is False: raise ValidationError( "Your previous password is incorrect", field_names=["confirm"]) if existing_user: raise ValidationError( "Email address has already been used", field_names=["email"]) if check_email_is_whitelisted(email) is False: raise ValidationError( "Only email addresses under {domains} may register". format(domains=get_config("domain_whitelist")), field_names=["email"], ) if get_config("verify_emails"): current_user.verified = False
def scores_visible(): v = get_config("score_visibility") if v == "public": return True elif v == "private": return authed() elif v == "hidden": return False elif v == "admins": return is_admin()
def get(self, user_id): 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 _require_verified_emails(*args, **kwargs): if get_config("verify_emails"): if current_user.authed(): if (current_user.is_admin() is False and current_user.is_verified() is False): # User is not confirmed if request.content_type == "application/json": abort(403) else: return redirect(url_for("auth.confirm")) return f(*args, **kwargs)
def get(self): user = get_current_user() awards = user.get_awards(admin=True) 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 = get_current_user() solves = user.get_solves(admin=True) 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 delete(self, token_id): if is_admin(): token = Tokens.query.filter_by(id=token_id).first_or_404() else: user = get_current_user() token = Tokens.query.filter_by(id=token_id, user_id=user.id).first_or_404() db.session.delete(token) db.session.commit() db.session.close() return {"success": True}
def get(self): team = get_current_team() solves = team.get_solves(admin=True) 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 during_ctf_time_only_wrapper(*args, **kwargs): if ctftime() or current_user.is_admin(): return f(*args, **kwargs) else: if ctf_ended(): if view_after_ctf(): return f(*args, **kwargs) else: error = "{} has ended".format(config.ctf_name()) abort(403, description=error) if ctf_started() is False: error = "{} has not started yet".format(config.ctf_name()) abort(403, description=error)
def get(self, team_id): team = Teams.query.filter_by(id=team_id).first_or_404() view = "admin" if is_admin() else "user" schema = TeamSchema(view=view) response = schema.dump(team) if response.errors: return {"success": False, "errors": response.errors}, 400 members = response.data.get("members") return {"success": True, "data": members}
def get(self, team_id): 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, challenge_id): response = [] challenge = Challenges.query.filter_by(id=challenge_id).first_or_404() # TODO: Need a generic challenge visibility call. # However, it should be stated that a solve on a gated challenge is not considered private. if challenge.state == "hidden" and is_admin() is False: abort(404) Model = get_model() solves = (Solves.query.join(Model, Solves.account_id == Model.id).filter( Solves.challenge_id == challenge_id, Model.banned == False, Model.hidden == False, ).order_by(Solves.date.asc())) freeze = get_config("freeze") if freeze: preview = request.args.get("preview") if (is_admin() is False) or (is_admin() is True and preview): dt = datetime.datetime.utcfromtimestamp(freeze) solves = solves.filter(Solves.date < dt) for solve in solves: response.append({ "account_id": solve.account_id, "name": solve.account.name, "date": isoformat(solve.date), "account_url": generate_account_url(account_id=solve.account_id), }) return {"success": True, "data": response}
def get(self, token_id): if is_admin(): token = Tokens.query.filter_by(id=token_id).first_or_404() else: token = Tokens.query.filter_by( id=token_id, user_id=session["id"]).first_or_404() schema = TokenSchema(view=session.get("type", "user")) response = schema.dump(token) if response.errors: return {"success": False, "errors": response.errors}, 400 return {"success": True, "data": response.data}
def get(self, user_id): user = Users.query.filter_by(id=user_id).first_or_404() if (user.banned or user.hidden) and is_admin() is False: abort(404) response = UserSchema(view=session.get("type", "user")).dump(user) if response.errors: return {"success": False, "errors": response.errors}, 400 response.data["place"] = user.place response.data["score"] = user.score return {"success": True, "data": response.data}
def get(self, team_id): team = Teams.query.filter_by(id=team_id).first_or_404() if (team.banned or team.hidden) and is_admin() is False: abort(404) view = TeamSchema.views.get(session.get("type", "user")) schema = TeamSchema(view=view) response = schema.dump(team) if response.errors: return {"success": False, "errors": response.errors}, 400 response.data["place"] = team.place response.data["score"] = team.score return {"success": True, "data": response.data}
def validate_name(self, data): name = data.get("name") if name is None: return name = name.strip() existing_team = Teams.query.filter_by(name=name).first() current_team = get_current_team() # Admins should be able to patch anyone but they cannot cause a collision. if is_admin(): team_id = int(data.get("id", 0)) if team_id: if existing_team and existing_team.id != team_id: raise ValidationError( "Team name has already been taken", field_names=["name"] ) else: # If there's no Team ID it means that the admin is creating a team with no ID. if existing_team: if current_team: if current_team.id != existing_team.id: raise ValidationError( "Team name has already been taken", field_names=["name"] ) else: raise ValidationError( "Team name has already been taken", field_names=["name"] ) else: # We need to allow teams to edit themselves and allow the "conflict" if data["name"] == current_team.name: return data else: name_changes = get_config("name_changes", default=True) if bool(name_changes) is False: raise ValidationError( "Name changes are disabled", field_names=["name"] ) if existing_team: raise ValidationError( "Team name has already been taken", field_names=["name"] )