def test_api_admin_can_change_captain(): """Can admins/captains change captains for teams""" app = create_ctfd(user_mode="teams") with app.app_context(): user1 = gen_user(app.db, name="user1", email="*****@*****.**") # ID 2 user2 = gen_user(app.db, name="user2", email="*****@*****.**") # ID 3 team = gen_team(app.db) team.members.append(user1) team.members.append(user2) team.captain_id = 2 user1.team_id = team.id user2.team_id = team.id app.db.session.commit() # I am not the captain with login_as_user(app, name="user2") as client: r = client.patch("/api/v1/teams/1", json={"captain_id": 3}) assert r.status_code == 403 # Look at me, I'm the captain now with login_as_user(app, name="user1") as client: r = client.patch("/api/v1/teams/1", json={"captain_id": 3}) # We should still receive a 403 because admins are the only people who can change captains for specific teams assert r.status_code == 403 # Escalate to admin with login_as_user(app, name="admin") as client: r = client.patch("/api/v1/teams/1", json={"captain_id": 3}) resp = r.get_json() assert resp["data"]["captain_id"] == 3 assert r.status_code == 200 destroy_ctfd(app)
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="*****@*****.**") # ID 2 user2 = gen_user(app.db, name="user2", email="*****@*****.**") # 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 app.db.session.commit() with login_as_user(app, name="user1") as client: r = client.delete('/api/v1/teams/1/members', json={'id': 2}) assert r.status_code == 403 with login_as_user(app, name="admin") as client: r = client.delete('/api/v1/teams/1/members', json={'id': 2}) assert r.status_code == 200 resp = r.get_json() assert resp['data'] == [3] r = client.delete('/api/v1/teams/1/members', json={'id': 2}) resp = r.get_json() assert 'User is not part of this team' in resp['errors']['id'] assert r.status_code == 400 destroy_ctfd(app)
def test_api_challenge_list_verified_emails(): """Can a verified email load /api/v1/challenges""" app = create_ctfd() with app.app_context(), freeze_time("2017-10-5"): set_config( "start", "1507089600" ) # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST set_config( "end", "1507262400" ) # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST set_config("verify_emails", True) register_user(app) client = login_as_user(app) r = client.get("/api/v1/challenges") assert r.status_code == 302 gen_user( app.db, name="user_name", email="*****@*****.**", password="******", verified=True, ) registered_client = login_as_user(app, "user_name", "password") r = registered_client.get("/api/v1/challenges") assert r.status_code == 200 destroy_ctfd(app)
def test_api_team_captain_disbanding(): """Test that only team captains can disband teams""" app = create_ctfd(user_mode="teams") with app.app_context(): user = gen_user(app.db, name="user") team = gen_team(app.db) team.members.append(user) user.team_id = team.id team.captain_id = 2 user2 = gen_user(app.db, name="user2", email="*****@*****.**") team.members.append(user2) app.db.session.commit() with login_as_user(app, name="user2") as client: r = client.delete("/api/v1/teams/me", json="") assert r.status_code == 403 assert r.get_json() == { "success": False, "errors": { "": ["Only team captains can disband their team"] }, } with login_as_user(app) as client: r = client.delete("/api/v1/teams/me", json="") assert r.status_code == 200 assert r.get_json() == { "success": True, } destroy_ctfd(app)
def test_ctfd_setup_verification(): app = create_ctfd(setup=False) with app.app_context(): with app.test_client() as client: r = client.get("/setup") assert r.status_code == 200 with client.session_transaction() as sess: data = { "ctf_name": "CTFd", "ctf_description": "CTF description", "name": "test", "email": "*****@*****.**", "password": "", "user_mode": "users", "nonce": sess.get("nonce"), } r = client.post("/setup", data=data) assert "longer password" in r.get_data(as_text=True) gen_user(app.db, name="test", email="*****@*****.**") data["password"] = "******" r = client.post("/setup", data=data) resp = r.get_data(as_text=True) assert "email has already been used" in resp assert "name is already taken" in resp data["name"] = "admin" data["email"] = "*****@*****.**" r = client.post("/setup", data=data) assert r.status_code == 302 assert r.location == "http://localhost/" destroy_ctfd(app)
def test_api_users_can_change_captain_on_self_team(): """Can admins/captains change captains for their own team""" app = create_ctfd(user_mode="teams") with app.app_context(): user1 = gen_user(app.db, name="user1", email="*****@*****.**") # ID 2 user2 = gen_user(app.db, name="user2", email="*****@*****.**") # ID 3 team = gen_team(app.db) team.members.append(user1) team.members.append(user2) team.captain_id = 2 user1.team_id = team.id user2.team_id = team.id app.db.session.commit() # 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 == 403 # Look at me, I'm the captain now with login_as_user(app, name="user1") as client: r = client.patch("/api/v1/teams/me", json={"captain_id": 3}) resp = r.get_json() assert resp["data"]["captain_id"] == 3 assert r.status_code == 200 destroy_ctfd(app)
def test_hint_team_unlocking_without_points(): """Test that teams cannot enter negative point valuations from unlocking hints""" app = create_ctfd(user_mode="teams") with app.app_context(): user = gen_user(app.db) second_user = gen_user(app.db, name="user", email="*****@*****.**") team = gen_team(app.db) user.team_id = team.id second_user.team_id = team.id team.members.append(user) team.members.append(second_user) chal = gen_challenge(app.db) gen_hint(app.db, chal.id, content="hint", cost=1, type="standard") app.db.session.commit() with login_as_user(app, name="user_name") as client: # Assert that we don't see a hint r = client.get("/api/v1/hints/1") assert r.get_json()["data"].get("content") is None # Attempt to unlock the hint r = client.post("/api/v1/unlocks", json={ "target": 1, "type": "hints" }) assert r.status_code == 400 assert (r.get_json()["errors"]["score"] == "You do not have enough points to unlock this hint") destroy_ctfd(app)
def test_api_tag_detail_get(): """Can a user get /api/v1/tokens/<token_id>""" app = create_ctfd() with app.app_context(): user = gen_user(app.db, name="user") generate_user_token(user) with login_as_user(app) as client: r = client.get("/api/v1/tokens/1", json="") assert r.status_code == 200 resp = r.get_json() assert sorted(resp["data"].keys()) == sorted( TokenSchema().views["user"]) with login_as_user(app, "admin") as client: r = client.get("/api/v1/tokens/1", json="") assert r.status_code == 200 resp = r.get_json() assert sorted(resp["data"].keys()) == sorted( TokenSchema().views["admin"]) gen_user(app.db, name="user2", email="*****@*****.**") with login_as_user(app, "user2") as client: r = client.get("/api/v1/tokens/1", json="") assert r.status_code == 404 destroy_ctfd(app)
def test_challenge_team_submit(): """Is a user's solved challenge reflected by other team members""" app = create_ctfd(user_mode="teams") with app.app_context(): user = gen_user(app.db) second_user = gen_user(app.db, name="user", email='*****@*****.**') team = gen_team(app.db) user.team_id = team.id second_user.team_id = team.id team.members.append(user) team.members.append(second_user) gen_challenge(app.db) gen_flag(app.db, 1) app.db.session.commit() with login_as_user(app, name="user_name") as client: flag = {"challenge_id": 1, "submission": "flag"} client.post('/api/v1/challenges/attempt', json=flag) with login_as_user(app) as second_client: flag = {"challenge_id": 1, "submission": "flag"} r = second_client.post('/api/v1/challenges/attempt', json=flag) assert r.json['data']['status'] == 'already_solved' standings = get_standings() assert standings[0][2] == "team_name" assert standings[0][3] == 100 destroy_ctfd(app)
def test_user_token_access(): app = create_kmactf() with app.app_context(): with app.test_client() as client: r = client.get("/api/v1/users/me", json="") assert r.status_code == 403 with app.test_client() as client: user = gen_user(app.db, name="user2", email="*****@*****.**") expiration = datetime.datetime.utcnow() + datetime.timedelta( days=-1) token = generate_user_token(user, expiration=expiration) headers = {"Authorization": "token " + token.value} r = client.get("/api/v1/users/me", headers=headers, json="") assert r.status_code == 401 with app.test_client() as client: headers = {"Authorization": "token invalid_token"} r = client.get("/api/v1/users/me", headers=headers, json="") assert r.status_code == 401 with app.test_client() as client: user = gen_user(app.db, name="user1", email="*****@*****.**") token = generate_user_token(user, expiration=None) headers = {"Authorization": "token " + token.value} r = client.get("/api/v1/users/me", headers=headers, json="") assert r.status_code == 200 resp = r.get_json() assert resp["data"]["email"] == "*****@*****.**" assert resp["data"]["name"] == "user1" destroy_kmactf(app)
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(): team = gen_team(app.db) 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={"user_id": 2}) assert r.status_code == 403 with login_as_user(app, name="admin") as client: r = client.delete("/api/v1/teams/1/members", json={"user_id": 2}) assert r.status_code == 200 resp = r.get_json() # 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={"user_id": 2}) resp = r.get_json() assert "User is not part of this team" in resp["errors"]["id"] assert r.status_code == 400 destroy_ctfd(app)
def test_hint_team_unlock(): """Is a user's unlocked hint reflected on other team members""" app = create_kmactf(user_mode="teams") with app.app_context(): user = gen_user(app.db) second_user = gen_user(app.db, name="user", email="*****@*****.**") team = gen_team(app.db) user.team_id = team.id second_user.team_id = team.id team.members.append(user) team.members.append(second_user) chal = gen_challenge(app.db) gen_hint(app.db, chal.id, content="hint", cost=1, type="standard") gen_award(app.db, 2, team.id) app.db.session.commit() with login_as_user(app, name="user_name") as client: client.get("/api/v1/hints/1") client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"}) client.get("/api/v1/hints/1") with login_as_user(app) as second_client: second_client.get("/api/v1/hints/1") second_client.post("/api/v1/unlocks", json={ "target": 1, "type": "hints" }) r = second_client.get("/api/v1/hints/1") assert r.json["data"]["content"] == "hint" standings = get_standings() assert standings[0][2] == "team_name" assert standings[0][3] == 99 destroy_kmactf(app)
def test_teams_join_when_already_on_team(): """Test that a user cannot join another team""" app = create_ctfd(user_mode="teams") with app.app_context(): gen_user(app.db, name="user") gen_team(app.db, email="*****@*****.**", name="team1") gen_team(app.db, email="*****@*****.**", name="team2") with login_as_user(app) as client: r = client.get("/teams/join") assert r.status_code == 200 with client.session_transaction() as sess: data = { "name": "team1", "password": "******", "nonce": sess.get("nonce"), } r = client.post("/teams/join", data=data) assert r.status_code == 302 # Try to join another team while on a team r = client.get("/teams/join") assert r.status_code == 200 with client.session_transaction() as sess: data = { "name": "team2", "password": "******", "nonce": sess.get("nonce"), } r = client.post("/teams/join", data=data) assert r.status_code == 403 user = Users.query.filter_by(name="user").first() assert user.team.name == "team1" destroy_ctfd(app)
def test_teams_new_post(): """Can a user post /teams/new""" app = create_ctfd(user_mode="teams") with app.app_context(): gen_user(app.db, name="user") with login_as_user(app) as client: with client.session_transaction() as sess: data = { "name": "team", "password": "******", "nonce": sess.get("nonce"), } r = client.post("/teams/new", data=data) assert r.status_code == 302 # You can't create a team with a duplicate name r = client.post("/teams/new", data=data) assert r.status_code == 403 # You can't create a team with an empty name incorrect_data = data incorrect_data["name"] = "" r = client.post("/teams/new", data=incorrect_data) assert r.status_code == 403 destroy_ctfd(app)
def test_hint_team_unlock(): """Is a user's unlocked hint reflected on other team members""" app = create_ctfd(user_mode="teams") with app.app_context(): user = gen_user(app.db) second_user = gen_user(app.db, name="user", email="*****@*****.**") team = gen_team(app.db) user.team_id = team.id second_user.team_id = team.id team.members.append(user) team.members.append(second_user) chal = gen_challenge(app.db) gen_hint(app.db, chal.id, content="hint", cost=1, type="standard") # Give the points to the user that doesn't unlock # Users that unlock hints should be able to unlock but cost their team points gen_award(app.db, user_id=3, team_id=team.id) app.db.session.commit() with login_as_user(app, name="user_name") as client: # Assert that we don't see a hint r = client.get("/api/v1/hints/1") assert r.get_json()["data"].get("content") is None # Unlock the hint client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"}) # Assert that we see a hint r = client.get("/api/v1/hints/1") assert r.get_json()["data"].get("content") with login_as_user(app) as second_client: # Assert that we see a hint r = second_client.get("/api/v1/hints/1") assert r.get_json()["data"].get("content") # Assert that we can't double unlock r = second_client.post("/api/v1/unlocks", json={ "target": 1, "type": "hints" }) assert r.status_code == 400 assert (r.get_json()["errors"]["target"] == "You've already unlocked this this target") # Assert that we see a hint r = second_client.get("/api/v1/hints/1") assert r.json["data"]["content"] == "hint" # Verify standings # We start with 100 points from the award. # We lose a point because we unlock successfully once standings = get_standings() assert standings[0][2] == "team_name" assert standings[0][3] == 99 destroy_ctfd(app)
def test_dynamic_challenge_loses_value_properly(): app = create_ctfd(enable_plugins=True) with app.app_context(): register_user(app) client = login_as_user(app, name="admin", password="******") challenge_data = { "name": "name", "category": "category", "description": "description", "value": 100, "decay": 20, "minimum": 1, "state": "visible", "type": "dynamic" } r = client.post('/api/v1/challenges', json=challenge_data) assert r.get_json().get('data')['id'] == 1 gen_flag(app.db, challenge_id=1, content='flag') for i, team_id in enumerate(range(2, 26)): name = "user{}".format(team_id) email = "user{}@ctfd.io".format(team_id) # We need to bypass rate-limiting so gen_user instead of register_user gen_user(app.db, name=name, email=email) with app.test_client() as client: # We need to bypass rate-limiting so creating a fake user instead of logging in with client.session_transaction() as sess: sess['id'] = team_id sess['name'] = name sess['type'] = 'user' sess['email'] = email sess['nonce'] = 'fake-nonce' data = { "submission": 'flag', "challenge_id": 1 } r = client.post('/api/v1/challenges/attempt', json=data) resp = r.get_json()['data'] assert resp['status'] == 'correct' chal = DynamicChallenge.query.filter_by(id=1).first() if i >= 20: assert chal.value == chal.minimum else: assert chal.initial >= chal.value assert chal.value > chal.minimum destroy_ctfd(app)
def test_import_ctf(): """Test that CTFd can import a CTF""" app = create_ctfd() if not app.config.get("SQLALCHEMY_DATABASE_URI").startswith("sqlite"): with app.app_context(): base_user = "******" for x in range(10): user = base_user + str(x) user_email = user + "@ctfd.io" gen_user(app.db, name=user, email=user_email) base_team = "team" for x in range(5): team = base_team + str(x) team_email = team + "@ctfd.io" gen_team(app.db, name=team, email=team_email) for x in range(9): chal = gen_challenge(app.db, name="chal_name{}".format(x)) gen_flag(app.db, challenge_id=chal.id, content="flag") chal = gen_challenge(app.db, name="chal_name10", requirements={"prerequisites": [1]}) gen_flag(app.db, challenge_id=chal.id, content="flag") app.db.session.commit() backup = export_ctf() with open("export.test_import_ctf.zip", "wb") as f: f.write(backup.read()) destroy_ctfd(app) app = create_ctfd() # TODO: These databases should work but they don't... if not app.config.get("SQLALCHEMY_DATABASE_URI").startswith("sqlite"): with app.app_context(): import_ctf("export.test_import_ctf.zip") if not app.config.get("SQLALCHEMY_DATABASE_URI").startswith( "postgres"): # TODO: Dig deeper into why Postgres fails here assert Users.query.count() == 31 assert Teams.query.count() == 5 assert Challenges.query.count() == 10 assert Flags.query.count() == 10 chal = Challenges.query.filter_by(name="chal_name10").first() assert chal.requirements == {"prerequisites": [1]} destroy_ctfd(app)
def test_api_challenges_get_verified_emails(): """Can a verified email user get /api/v1/challenges""" app = create_ctfd() with app.app_context(): set_config('verify_emails', True) register_user(app) client = login_as_user(app) r = client.get('/api/v1/challenges', json="") assert r.status_code == 403 gen_user(app.db, name='user_name', email='*****@*****.**', password='******', verified=True) registered_client = login_as_user(app, 'user_name', 'password') r = registered_client.get('/api/v1/challenges') assert r.status_code == 200 destroy_ctfd(app)
def test_api_user_without_team_challenge_interaction(): """Can a user interact with challenges without having joined a team?""" app = create_ctfd(user_mode="teams") with app.app_context(): register_user(app) gen_challenge(app.db) gen_flag(app.db, 1) with login_as_user(app) as client: assert client.get('/api/v1/challenges').status_code == 403 assert client.get('/api/v1/challenges/1').status_code == 403 assert client.post('/api/v1/challenges/attempt', json={ "challenge_id": 1, "submission": "wrong_flag" }).status_code == 403 # Create a user with a team user = gen_user(app.db, email='*****@*****.**') team = gen_team(app.db) team.members.append(user) user.team_id = team.id app.db.session.commit() # Test if user with team can interact with challenges with login_as_user(app, name="user_name") as client: assert client.get('/api/v1/challenges').status_code == 200 assert client.get('/api/v1/challenges/1').status_code == 200 assert client.post('/api/v1/challenges/attempt', json={ "challenge_id": 1, "submission": "flag" }).status_code == 200 destroy_ctfd(app)
def test_api_team_patch_me_logged_in_admin_captain(): """Can an admin patch /api/v1/teams/me if logged in as a team captain""" app = create_ctfd(user_mode="teams") with app.app_context(): admin = Users.query.filter_by(id=1).first() user = gen_user(app.db) team = gen_team(app.db) team.members.append(user) team.members.append(admin) user.team_id = team.id admin.team_id = team.id # We want the admin to be the captain team.captain_id = 1 app.db.session.commit() with login_as_user(app, name="admin") as client: r = client.patch('/api/v1/teams/me', json={ "name": "team_name", "affiliation": "changed" }) assert r.status_code == 200 team = Teams.query.filter_by(id=1).first() assert team.name == "team_name" destroy_ctfd(app)
def test_api_team_patch_me_logged_in_admin_captain(): """Can an admin patch /api/v1/teams/me if logged in as a team captain""" app = create_ctfd(user_mode="teams") with app.app_context(): admin = Users.query.filter_by(id=1).first() user = gen_user(app.db) team = gen_team(app.db) team.members.append(user) team.members.append(admin) user.team_id = team.id admin.team_id = team.id # We want the admin to be the captain team.captain_id = 1 app.db.session.commit() with login_as_user(app, name="admin") as client: # Users can't null out their team name r = client.patch("/api/v1/teams/me", json={"name": None}) resp = r.get_json() assert r.status_code == 400 assert resp["errors"]["name"] == ["Field may not be null."] r = client.patch("/api/v1/teams/me", json={ "name": "team_name", "affiliation": "changed" }) assert r.status_code == 200 team = Teams.query.filter_by(id=1).first() assert team.name == "team_name" destroy_ctfd(app)
def test_reset(): app = create_kmactf() with app.app_context(): base_user = "******" for x in range(10): chal = gen_challenge(app.db, name="chal_name{}".format(x)) gen_flag(app.db, challenge_id=chal.id, content="flag") for x in range(10): user = base_user + str(x) user_email = user + "@kmactf.io" user_obj = gen_user(app.db, name=user, email=user_email) gen_award(app.db, user_id=user_obj.id) gen_solve(app.db, user_id=user_obj.id, challenge_id=random.randint(1, 10)) gen_fail(app.db, user_id=user_obj.id, challenge_id=random.randint(1, 10)) gen_tracking(app.db, user_id=user_obj.id) assert Users.query.count() == 11 # 11 because of the first admin user assert Challenges.query.count() == 10 register_user(app) client = login_as_user(app, name="admin", password="******") with client.session_transaction() as sess: data = {"nonce": sess.get("nonce")} client.post("/admin/reset", data=data) assert Users.query.count() == 0 assert Challenges.query.count() == 10 assert Solves.query.count() == 0 assert Fails.query.count() == 0 assert Tracking.query.count() == 0 destroy_kmactf(app)
def test_api_team_get_admin(): """Can a user get /api/v1/users/<user_id> if users are viewed by admins only""" app = create_ctfd() with app.app_context(): with login_as_user(app, "admin") as client: gen_user(app.db) set_config("account_visibility", "public") r = client.get("/api/v1/users/2") assert r.status_code == 200 set_config("account_visibility", "private") r = client.get("/api/v1/users/2") assert r.status_code == 200 set_config("account_visibility", "admins") r = client.get("/api/v1/users/2") assert r.status_code == 200 destroy_ctfd(app)
def test_api_team_get_public(): """Can a user get /api/v1/team/<user_id> if users are public""" app = create_ctfd() with app.app_context(): with app.test_client() as client: set_config("account_visibility", "public") gen_user(app.db) r = client.get("/api/v1/users/2") assert r.status_code == 200 set_config("account_visibility", "private") r = client.get("/api/v1/users/2") assert r.status_code == 302 set_config("account_visibility", "admins") r = client.get("/api/v1/users/2") assert r.status_code == 404 destroy_ctfd(app)
def test_lookup_user_token(): app = create_kmactf() with app.app_context(): user = gen_user(app.db) # Good Token token = gen_token(app.db, user_id=user.id) user = lookup_user_token(token.value) assert user.id == token.user_id # Expired Token expiration = datetime.datetime.utcnow() + datetime.timedelta(days=-1) token = gen_token(app.db, user_id=user.id, expiration=expiration) try: lookup_user_token(token.value) except UserTokenExpiredException: pass except Exception as e: raise e # Nonexistant token try: lookup_user_token("wat") except UserNotFoundException: pass except Exception as e: raise e destroy_kmactf(app)
def test_api_team_patch_password(): """Can a user change their team password /api/v1/teams/me if logged in as the captain""" app = create_ctfd(user_mode="teams") with app.app_context(): user1 = gen_user(app.db, name="user1", email="*****@*****.**") # ID 2 user2 = gen_user(app.db, name="user2", email="*****@*****.**") # ID 3 team = gen_team(app.db) team.members.append(user1) team.members.append(user2) team.captain_id = 2 user1.team_id = team.id user2.team_id = team.id app.db.session.commit() with login_as_user(app, name="user2") as client: r = client.patch( "/api/v1/teams/me", json={ "confirm": "password", "password": "******" }, ) assert r.status_code == 403 assert r.get_json() == { "errors": { "": ["Only team captains can edit team information"] }, "success": False, } team = Teams.query.filter_by(id=1).first() assert (verify_password(plaintext="new_password", ciphertext=team.password) is False) with login_as_user(app, name="user1") as client: r = client.patch( "/api/v1/teams/me", json={ "confirm": "password", "password": "******" }, ) assert r.status_code == 200 team = Teams.query.filter_by(id=1).first() assert verify_password(plaintext="new_password", ciphertext=team.password)
def test_api_challenge_get_verified_emails(): """Can a verified email load /api/v1/challenges/<challenge_id>""" app = create_ctfd() with app.app_context(), freeze_time("2017-10-5"): set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST set_config('verify_emails', True) gen_challenge(app.db) gen_user(app.db, name='user_name', email='*****@*****.**', password='******', verified=True) register_user(app) client = login_as_user(app) registered_client = login_as_user(app, 'user_name', 'password') r = client.get('/api/v1/challenges/1', json="") assert r.status_code == 403 r = registered_client.get('/api/v1/challenges/1') assert r.status_code == 200 destroy_ctfd(app)
def test_dynamic_challenge_loses_value_properly(): app = create_ctfd(enable_plugins=True) with app.app_context(): register_user(app) client = login_as_user(app, name="admin", password="******") challenge_data = { "name": "name", "category": "category", "description": "description", "value": 500, "initial": 500, "slope": 1.5, "decrease": 2.079, "state": "visible", "type": "dynamic", } r = client.post("/api/v1/challenges", json=challenge_data) assert r.get_json().get("data")["id"] == 1 gen_flag(app.db, challenge_id=1, content="flag") for i, team_id in enumerate(range(2, 26)): name = "user{}".format(team_id) email = "user{}@ctfd.io".format(team_id) # We need to bypass rate-limiting so gen_user instead of register_user user = gen_user(app.db, name=name, email=email) user_id = user.id with app.test_client() as client: # We need to bypass rate-limiting so creating a fake user instead of logging in with client.session_transaction() as sess: sess["id"] = user_id sess["nonce"] = "fake-nonce" sess["hash"] = hmac(user.password) data = {"submission": "flag", "challenge_id": 1} r = client.post("/api/v1/challenges/attempt", json=data) resp = r.get_json()["data"] assert resp["status"] == "correct" chal = DynamicChallenge.query.filter_by(id=1).first() assert chal.initial >= chal.value if i == 0: # The first solver should get the maximum points assert chal.initial == chal.value elif i == 10: # The value should be around half of the maximum by 10 solvers assert chal.value > 260 assert chal.value < 270 elif i == 250: assert chal.value > 95 assert chal.value < 105 destroy_ctfd(app)
def test_api_team_patch_me_logged_in_user(): """Can a user patch /api/v1/teams/me if logged in as a regular user""" app = create_ctfd(user_mode="teams") with app.app_context(): user1 = gen_user(app.db, name="user1", email="*****@*****.**") user2 = gen_user(app.db, name="user2", email="*****@*****.**") team = gen_team(app.db) team.members.append(user1) team.members.append(user2) user1.team_id = team.id user2.team_id = team.id app.db.session.commit() with login_as_user(app, name="user2") as client: r = client.patch( "/api/v1/teams/me", json={"name": "team_name", "affiliation": "changed"} ) assert r.status_code == 403 destroy_ctfd(app)
def test_generate_user_token(): app = create_kmactf() with app.app_context(): user = gen_user(app.db) token = generate_user_token(user, expiration=None) token.user_id == user.id assert token.expiration > datetime.datetime.utcnow() assert Tokens.query.count() == 1 destroy_kmactf(app)