diff --git a/tests/api/v1/test_fields.py b/tests/api/v1/test_fields.py index 4ddf136b..e461cd80 100644 --- a/tests/api/v1/test_fields.py +++ b/tests/api/v1/test_fields.py @@ -1,11 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from CTFd.models import Fields, UserFieldEntries +from CTFd.models import Fields, TeamFieldEntries, Teams, UserFieldEntries, Users from tests.helpers import ( create_ctfd, destroy_ctfd, gen_field, + gen_team, login_as_user, register_user, ) @@ -251,3 +252,165 @@ def test_partial_field_update(): ) destroy_ctfd(app) + + +def test_api_team_self_fields_permissions(): + app = create_ctfd(user_mode="teams") + with app.app_context(): + register_user(app) + team = gen_team(app.db) + user = Users.query.filter_by(id=2).first() + user.team_id = team.id + app.db.session.commit() + team = Teams.query.filter_by(id=1).first() + team.captain_id = 2 + app.db.session.commit() + + gen_field( + app.db, name="CustomField1", type="team", public=False, editable=False + ) + gen_field(app.db, name="CustomField2", type="team", public=True, editable=True) + + app.db.session.add( + TeamFieldEntries(type="team", value="CustomValue1", team_id=1, field_id=1) + ) + app.db.session.add( + TeamFieldEntries(type="team", value="CustomValue2", team_id=1, field_id=2) + ) + app.db.session.commit() + + assert len(team.field_entries) == 2 + + with login_as_user(app) as user, login_as_user(app, name="admin") as admin: + r = user.get("/api/v1/teams/me") + resp = r.get_json() + assert resp["data"]["fields"] == [ + { + "value": "CustomValue2", + "name": "CustomField2", + "description": "CustomFieldDescription", + "type": "text", + "field_id": 2, + } + ] + assert len(resp["data"]["fields"]) == 1 + + # Admin gets data and should see all fields + r = admin.get("/api/v1/teams/1") + resp = r.get_json() + assert len(resp["data"]["fields"]) == 2 + + r = user.patch( + "/api/v1/teams/me", + json={ + "fields": [ + {"field_id": 1, "value": "NewCustomValue1"}, + {"field_id": 2, "value": "NewCustomValue2"}, + ] + }, + ) + assert r.get_json() == { + "success": False, + "errors": {"fields": ["Field 'CustomField1' cannot be editted"]}, + } + assert r.status_code == 400 + assert ( + TeamFieldEntries.query.filter_by(id=1).first().value == "CustomValue1" + ) + assert ( + TeamFieldEntries.query.filter_by(id=2).first().value == "CustomValue2" + ) + + # After making the field public the user should see both fields + field = Fields.query.filter_by(id=1).first() + field.public = True + app.db.session.commit() + r = user.get("/api/v1/teams/me") + resp = r.get_json() + assert len(resp["data"]["fields"]) == 2 + + # Captain should be able to edit their values after it's made editable + field = Fields.query.filter_by(id=1).first() + field.editable = True + app.db.session.commit() + r = user.patch( + "/api/v1/teams/me", + json={ + "fields": [ + {"field_id": 1, "value": "NewCustomValue1"}, + {"field_id": 2, "value": "NewCustomValue2"}, + ] + }, + ) + print(r.get_json()) + assert r.status_code == 200 + assert ( + TeamFieldEntries.query.filter_by(id=1).first().value + == "NewCustomValue1" + ) + assert ( + TeamFieldEntries.query.filter_by(id=2).first().value + == "NewCustomValue2" + ) + destroy_ctfd(app) + + +def test_team_partial_field_update(): + app = create_ctfd(user_mode="teams") + with app.app_context(): + register_user(app) + team = gen_team(app.db) + user = Users.query.filter_by(id=2).first() + user.team_id = team.id + team = Teams.query.filter_by(id=1).first() + team.captain_id = 2 + app.db.session.commit() + + gen_field(app.db, name="CustomField1", type="team") + gen_field(app.db, name="CustomField2", type="team") + + with login_as_user(app) as user: + r = user.patch( + "/api/v1/teams/me", + json={ + "fields": [ + {"field_id": 1, "value": "CustomValue1"}, + {"field_id": 2, "value": "CustomValue2"}, + ] + }, + ) + assert r.status_code == 200 + assert TeamFieldEntries.query.count() == 2 + + r = user.patch( + "/api/v1/teams/me", + json={"fields": [{"field_id": 2, "value": "NewCustomValue2"}]}, + ) + assert r.status_code == 200 + assert TeamFieldEntries.query.count() == 2 + assert ( + TeamFieldEntries.query.filter_by(field_id=1, team_id=1).first().value + == "CustomValue1" + ) + assert ( + TeamFieldEntries.query.filter_by(field_id=2, team_id=1).first().value + == "NewCustomValue2" + ) + + with login_as_user(app, name="admin") as admin: + r = admin.patch( + "/api/v1/teams/1", + json={"fields": [{"field_id": 2, "value": "AdminNewCustomValue2"}]}, + ) + assert r.status_code == 200 + assert TeamFieldEntries.query.count() == 2 + assert ( + TeamFieldEntries.query.filter_by(field_id=1, team_id=1).first().value + == "CustomValue1" + ) + assert ( + TeamFieldEntries.query.filter_by(field_id=2, team_id=1).first().value + == "AdminNewCustomValue2" + ) + + destroy_ctfd(app)