mirror of
https://github.com/aljazceru/CTFd.git
synced 2026-02-23 15:14:49 +01:00
Adds ondelete='CASCADE' to some models. (#979)
* Fixes `populate.py` to assign captains to teams.
* Adds `ondelete='CASCADE'` to most ForeignKeys in models
* Closes #794
* Test reset in team mode to test removing teams with captains
* Test deleting users/teams with awards to test cascading deletion
* `gen_team()` test helper now creates users for the team and assigns the first one as captain
* Added `Challenges.flags` relationship and moved the `Flags.challenge` relationship to a backref on `Challenges`
This commit is contained in:
@@ -14,11 +14,10 @@ def test_api_team_get_members():
|
||||
"""Can a user get /api/v1/teams/<team_id>/members only if admin"""
|
||||
app = create_ctfd(user_mode="teams")
|
||||
with app.app_context():
|
||||
user = gen_user(app.db)
|
||||
team = gen_team(app.db)
|
||||
team.members.append(user)
|
||||
user.team_id = team.id
|
||||
gen_team(app.db)
|
||||
app.db.session.commit()
|
||||
|
||||
gen_user(app.db, name="user_name")
|
||||
with login_as_user(app, name="user_name") as client:
|
||||
r = client.get('/api/v1/teams/1/members', json="")
|
||||
assert r.status_code == 403
|
||||
@@ -28,7 +27,8 @@ def test_api_team_get_members():
|
||||
assert r.status_code == 200
|
||||
|
||||
resp = r.get_json()
|
||||
assert resp['data'] == [2]
|
||||
# The following data is sorted b/c in Postgres data isn't necessarily returned ordered.
|
||||
assert sorted(resp['data']) == sorted([2, 3, 4, 5])
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
@@ -36,14 +36,11 @@ def test_api_team_remove_members():
|
||||
"""Can a user remove /api/v1/teams/<team_id>/members only if admin"""
|
||||
app = create_ctfd(user_mode="teams")
|
||||
with app.app_context():
|
||||
user1 = gen_user(app.db, name="user1", email="user1@ctfd.io") # ID 2
|
||||
user2 = gen_user(app.db, name="user2", email="user2@ctfd.io") # ID 3
|
||||
team = gen_team(app.db)
|
||||
team.members.append(user1)
|
||||
team.members.append(user2)
|
||||
user1.team_id = team.id
|
||||
user2.team_id = team.id
|
||||
assert len(team.members) == 4
|
||||
app.db.session.commit()
|
||||
|
||||
gen_user(app.db, name='user1')
|
||||
with login_as_user(app, name="user1") as client:
|
||||
r = client.delete('/api/v1/teams/1/members', json={
|
||||
'id': 2
|
||||
@@ -57,7 +54,8 @@ def test_api_team_remove_members():
|
||||
assert r.status_code == 200
|
||||
|
||||
resp = r.get_json()
|
||||
assert resp['data'] == [3]
|
||||
# The following data is sorted b/c in Postgres data isn't necessarily returned ordered.
|
||||
assert sorted(resp['data']) == sorted([3, 4, 5])
|
||||
|
||||
r = client.delete('/api/v1/teams/1/members', json={
|
||||
'id': 2
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from CTFd.models import Users
|
||||
from CTFd.models import Users, Challenges, Tags, Hints, Flags
|
||||
from CTFd.utils import set_config
|
||||
from tests.helpers import (create_ctfd,
|
||||
destroy_ctfd,
|
||||
register_user,
|
||||
login_as_user,
|
||||
gen_challenge,
|
||||
gen_flag,
|
||||
gen_user,
|
||||
gen_team,
|
||||
gen_solve,
|
||||
gen_fail)
|
||||
from tests.helpers import (
|
||||
create_ctfd,
|
||||
destroy_ctfd,
|
||||
register_user,
|
||||
login_as_user,
|
||||
gen_challenge,
|
||||
gen_flag,
|
||||
gen_tag,
|
||||
gen_hint,
|
||||
gen_user,
|
||||
gen_team,
|
||||
gen_solve,
|
||||
gen_fail
|
||||
)
|
||||
from freezegun import freeze_time
|
||||
|
||||
|
||||
@@ -283,7 +287,7 @@ def test_api_challenge_delete_non_admin():
|
||||
|
||||
|
||||
def test_api_challenge_delete_admin():
|
||||
"""Can a user patch /api/v1/challenges/<challenge_id> if admin"""
|
||||
"""Can a user delete /api/v1/challenges/<challenge_id> if admin"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
gen_challenge(app.db)
|
||||
@@ -294,6 +298,32 @@ def test_api_challenge_delete_admin():
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_api_challenge_with_properties_delete_admin():
|
||||
"""Can a user delete /api/v1/challenges/<challenge_id> if the challenge has other properties"""
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
challenge = gen_challenge(app.db)
|
||||
gen_hint(app.db, challenge_id=challenge.id)
|
||||
gen_tag(app.db, challenge_id=challenge.id)
|
||||
gen_flag(app.db, challenge_id=challenge.id)
|
||||
|
||||
challenge = Challenges.query.filter_by(id=1).first()
|
||||
assert len(challenge.hints) == 1
|
||||
assert len(challenge.tags) == 1
|
||||
assert len(challenge.flags) == 1
|
||||
|
||||
with login_as_user(app, 'admin') as client:
|
||||
r = client.delete('/api/v1/challenges/1', json="")
|
||||
assert r.status_code == 200
|
||||
assert r.get_json().get('data') is None
|
||||
|
||||
assert Tags.query.count() == 0
|
||||
assert Hints.query.count() == 0
|
||||
assert Flags.query.count() == 0
|
||||
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
def test_api_challenge_attempt_post_public():
|
||||
"""Can a public user post /api/v1/challenges/attempt"""
|
||||
app = create_ctfd()
|
||||
|
||||
@@ -4,14 +4,17 @@
|
||||
from CTFd.models import Teams, Users
|
||||
from CTFd.utils import set_config
|
||||
from CTFd.utils.crypto import verify_password
|
||||
from tests.helpers import (create_ctfd,
|
||||
destroy_ctfd,
|
||||
register_user,
|
||||
login_as_user,
|
||||
gen_user,
|
||||
gen_team,
|
||||
gen_challenge,
|
||||
gen_flag)
|
||||
from tests.helpers import (
|
||||
create_ctfd,
|
||||
destroy_ctfd,
|
||||
register_user,
|
||||
login_as_user,
|
||||
gen_user,
|
||||
gen_team,
|
||||
gen_challenge,
|
||||
gen_flag,
|
||||
simulate_user_activity
|
||||
)
|
||||
|
||||
|
||||
def test_api_teams_get_public():
|
||||
@@ -262,11 +265,21 @@ def test_api_team_delete_admin():
|
||||
"""Can a user patch /api/v1/teams/<team_id> if admin"""
|
||||
app = create_ctfd(user_mode="teams")
|
||||
with app.app_context():
|
||||
gen_team(app.db)
|
||||
team = gen_team(app.db)
|
||||
|
||||
assert len(team.members) == 4
|
||||
|
||||
members = team.members
|
||||
for user in members:
|
||||
simulate_user_activity(app.db, user=user)
|
||||
|
||||
with login_as_user(app, 'admin') as client:
|
||||
r = client.delete('/api/v1/teams/1', json="")
|
||||
assert r.status_code == 200
|
||||
assert r.get_json().get('data') is None
|
||||
|
||||
for user in Users.query.all():
|
||||
assert user.team_id is None
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@ from CTFd.models import Users
|
||||
from CTFd.utils import set_config
|
||||
from CTFd.utils.crypto import verify_password
|
||||
from CTFd.schemas.users import UserSchema
|
||||
from tests.helpers import (create_ctfd,
|
||||
destroy_ctfd,
|
||||
register_user,
|
||||
login_as_user,
|
||||
gen_user)
|
||||
from tests.helpers import (
|
||||
create_ctfd,
|
||||
destroy_ctfd,
|
||||
register_user,
|
||||
login_as_user,
|
||||
gen_user,
|
||||
simulate_user_activity
|
||||
)
|
||||
|
||||
|
||||
def test_api_users_get_public():
|
||||
@@ -322,10 +325,13 @@ def test_api_user_delete_admin():
|
||||
app = create_ctfd()
|
||||
with app.app_context():
|
||||
register_user(app)
|
||||
user = Users.query.filter_by(id=2).first()
|
||||
simulate_user_activity(app.db, user=user)
|
||||
with login_as_user(app, 'admin') as client:
|
||||
r = client.delete('/api/v1/users/2', json="")
|
||||
assert r.status_code == 200
|
||||
assert r.get_json().get('data') is None
|
||||
assert Users.query.filter_by(id=2).first() is None
|
||||
destroy_ctfd(app)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user