1423 model filter bypass (#1451)

* Add `view=admin` GET param to `/api/v1/users`, `/api/v1/teams`, and `/api/v1/challenges` to bypass filtering for admins
* Closes #1423 #1445
* Related to #1165
This commit is contained in:
Kevin Chung
2020-05-29 11:06:04 -04:00
committed by GitHub
parent 970e1ca65e
commit 50f75be5eb
6 changed files with 76 additions and 23 deletions

View File

@@ -47,6 +47,11 @@ class ChallengeList(Resource):
# 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.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")

View File

@@ -22,7 +22,11 @@ teams_namespace = Namespace("teams", description="Endpoint to retrieve Teams")
class TeamList(Resource):
@check_account_visibility
def get(self):
if is_admin() and request.args.get("view") == "admin":
teams = Teams.query.filter_by()
else:
teams = Teams.query.filter_by(hidden=False, banned=False)
user_type = get_current_user_type(fallback="user")
view = copy.deepcopy(TeamSchema.views.get(user_type))
view.remove("members")

View File

@@ -31,7 +31,11 @@ users_namespace = Namespace("users", description="Endpoint to retrieve Users")
class UserList(Resource):
@check_account_visibility
def get(self):
if is_admin() and request.args.get("view") == "admin":
users = Users.query.filter_by()
else:
users = Users.query.filter_by(banned=False, hidden=False)
response = UserSchema(view="user", many=True).dump(users)
if response.errors:

View File

@@ -135,6 +135,25 @@ def test_api_challenges_get_admin():
destroy_ctfd(app)
def test_api_challenges_get_hidden_admin():
"""Can an admin see hidden challenges in API list response"""
app = create_ctfd()
with app.app_context():
gen_challenge(app.db, state="hidden")
gen_challenge(app.db)
with login_as_user(app, "admin") as admin:
challenges_list = admin.get("/api/v1/challenges", json="").get_json()[
"data"
]
assert len(challenges_list) == 1
challenges_list = admin.get(
"/api/v1/challenges?view=admin", json=""
).get_json()["data"]
assert len(challenges_list) == 2
destroy_ctfd(app)
def test_api_challenges_post_admin():
"""Can a user post /api/v1/challenges if admin"""
app = create_ctfd()

View File

@@ -696,6 +696,9 @@ def test_api_accessing_hidden_banned_users():
app.db.session.commit()
with login_as_user(app, name="visible_user") as client:
list_teams = client.get("/api/v1/teams").get_json()["data"]
assert len(list_teams) == 0
assert client.get("/api/v1/teams/1").status_code == 404
assert client.get("/api/v1/teams/1/solves").status_code == 404
assert client.get("/api/v1/teams/1/fails").status_code == 404
@@ -707,6 +710,10 @@ def test_api_accessing_hidden_banned_users():
assert client.get("/api/v1/teams/2/awards").status_code == 404
with login_as_user(app, name="admin") as client:
# Admins see hidden teams in lists
list_users = client.get("/api/v1/teams?view=admin").get_json()["data"]
assert len(list_users) == 2
assert client.get("/api/v1/teams/1").status_code == 200
assert client.get("/api/v1/teams/1/solves").status_code == 200
assert client.get("/api/v1/teams/1/fails").status_code == 200

View File

@@ -764,12 +764,19 @@ def test_api_accessing_hidden_users():
app.db.session.commit()
with login_as_user(app, name="visible_user") as client:
list_users = client.get("/api/v1/users").get_json()["data"]
assert len(list_users) == 1
assert client.get("/api/v1/users/3").status_code == 404
assert client.get("/api/v1/users/3/solves").status_code == 404
assert client.get("/api/v1/users/3/fails").status_code == 404
assert client.get("/api/v1/users/3/awards").status_code == 404
with login_as_user(app, name="admin") as client:
# Admins see the user in lists
list_users = client.get("/api/v1/users?view=admin").get_json()["data"]
assert len(list_users) == 3
assert client.get("/api/v1/users/3").status_code == 200
assert client.get("/api/v1/users/3/solves").status_code == 200
assert client.get("/api/v1/users/3/fails").status_code == 200
@@ -788,12 +795,19 @@ def test_api_accessing_banned_users():
app.db.session.commit()
with login_as_user(app, name="visible_user") as client:
list_users = client.get("/api/v1/users").get_json()["data"]
assert len(list_users) == 1
assert client.get("/api/v1/users/3").status_code == 404
assert client.get("/api/v1/users/3/solves").status_code == 404
assert client.get("/api/v1/users/3/fails").status_code == 404
assert client.get("/api/v1/users/3/awards").status_code == 404
with login_as_user(app, name="admin") as client:
# Admins see the user in lists
list_users = client.get("/api/v1/users?view=admin").get_json()["data"]
assert len(list_users) == 3
assert client.get("/api/v1/users/3").status_code == 200
assert client.get("/api/v1/users/3/solves").status_code == 200
assert client.get("/api/v1/users/3/fails").status_code == 200