From b453125726b7f0703eca69c278336d63c18fbdcd Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Fri, 12 Jul 2019 00:53:35 -0400 Subject: [PATCH] Fix missing Team API exceptions (#1058) * Add require_team decorator to endpoints that request teams. * Change status code for captain endpoints to return 403 instead of 400 --- CTFd/api/v1/teams.py | 9 +++++++-- CTFd/utils/decorators/__init__.py | 5 ++++- tests/api/v1/teams/test_team_members.py | 2 +- tests/api/v1/test_teams.py | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CTFd/api/v1/teams.py b/CTFd/api/v1/teams.py index 97e2ed8..2e471aa 100644 --- a/CTFd/api/v1/teams.py +++ b/CTFd/api/v1/teams.py @@ -10,7 +10,7 @@ from CTFd.utils.decorators.visibility import ( check_score_visibility, ) from CTFd.utils.user import get_current_team, is_admin -from CTFd.utils.decorators import authed_only, admins_only +from CTFd.utils.decorators import authed_only, admins_only, require_team import copy teams_namespace = Namespace("teams", description="Endpoint to retrieve Teams") @@ -110,6 +110,7 @@ class TeamPublic(Resource): @teams_namespace.param("team_id", "Current Team") class TeamPrivate(Resource): @authed_only + @require_team def get(self): team = get_current_team() response = TeamSchema(view="self").dump(team) @@ -120,6 +121,7 @@ class TeamPrivate(Resource): return {"success": True, "data": response.data} @authed_only + @require_team def patch(self): team = get_current_team() if team.captain_id != session["id"]: @@ -128,7 +130,7 @@ class TeamPrivate(Resource): "success": False, "errors": {"": ["Only team captains can edit team information"]}, }, - 400, + 403, ) data = request.get_json() @@ -226,6 +228,7 @@ class TeamMembers(Resource): @teams_namespace.route("/me/solves") class TeamPrivateSolves(Resource): @authed_only + @require_team def get(self): team = get_current_team() solves = team.get_solves(admin=True) @@ -243,6 +246,7 @@ class TeamPrivateSolves(Resource): @teams_namespace.route("/me/fails") class TeamPrivateFails(Resource): @authed_only + @require_team def get(self): team = get_current_team() fails = team.get_fails(admin=True) @@ -267,6 +271,7 @@ class TeamPrivateFails(Resource): @teams_namespace.route("/me/awards") class TeamPrivateAwards(Resource): @authed_only + @require_team def get(self): team = get_current_team() awards = team.get_awards(admin=True) diff --git a/CTFd/utils/decorators/__init__.py b/CTFd/utils/decorators/__init__.py index db836dc..e262b3b 100644 --- a/CTFd/utils/decorators/__init__.py +++ b/CTFd/utils/decorators/__init__.py @@ -118,7 +118,10 @@ def require_team(f): if get_config("user_mode") == TEAMS_MODE: team = get_current_team() if team is None: - return redirect(url_for("teams.private", next=request.full_path)) + if request.content_type == "application/json": + abort(403) + else: + return redirect(url_for("teams.private", next=request.full_path)) return f(*args, **kwargs) return require_team_wrapper diff --git a/tests/api/v1/teams/test_team_members.py b/tests/api/v1/teams/test_team_members.py index c0bfa9d..460b0d1 100644 --- a/tests/api/v1/teams/test_team_members.py +++ b/tests/api/v1/teams/test_team_members.py @@ -106,7 +106,7 @@ def test_api_users_can_change_captain_on_self_team(): # I am not the captain with login_as_user(app, name="user2") as client: r = client.patch("/api/v1/teams/me", json={"captain_id": 3}) - assert r.status_code == 400 + assert r.status_code == 403 # Look at me, I'm the captain now with login_as_user(app, name="user1") as client: diff --git a/tests/api/v1/test_teams.py b/tests/api/v1/test_teams.py index 44ae800..b4fcf17 100644 --- a/tests/api/v1/test_teams.py +++ b/tests/api/v1/test_teams.py @@ -339,7 +339,7 @@ def test_api_team_patch_me_logged_in_user(): r = client.patch( "/api/v1/teams/me", json={"name": "team_name", "affiliation": "changed"} ) - assert r.status_code == 400 + assert r.status_code == 403 destroy_ctfd(app) @@ -640,7 +640,7 @@ def test_api_team_patch_password(): "/api/v1/teams/me", json={"confirm": "password", "password": "new_password"}, ) - assert r.status_code == 400 + assert r.status_code == 403 assert r.get_json() == { "errors": {"": ["Only team captains can edit team information"]},