Example #1
0
def test_api_team_place_hidden_if_scores_hidden():
    """/api/v1/teams/me should not reveal team place if scores aren't visible"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        gen_team(app.db)
        app.db.session.commit()

        gen_award(app.db, user_id=2, team_id=1)

        u = Users.query.filter_by(id=2).first()

        with login_as_user(app, name=u.name) as client:
            r = client.get("/api/v1/teams/me", json="")
            resp = r.get_json()
            assert resp["data"]["place"] == "1st"

        set_config("score_visibility", "hidden")
        with login_as_user(app, name=u.name) as client:
            r = client.get("/api/v1/teams/me", json="")
            resp = r.get_json()
            assert resp["data"]["place"] is None

        set_config("score_visibility", "admins")
        with login_as_user(app, name=u.name) as client:
            r = client.get("/api/v1/teams/me", json="")
            resp = r.get_json()
            assert resp["data"]["place"] is None

        with login_as_user(app, name="admin") as client:
            r = client.get("/api/v1/teams/1", json="")
            resp = r.get_json()
            print(resp)
            assert resp["data"]["place"] == "1st"
    destroy_ctfd(app)
Example #2
0
def test_num_teams_limit():
    """Only num_teams teams can be created"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        set_config("num_teams", 1)

        # Create a team
        gen_team(app.db, member_count=1)

        register_user(app)
        with login_as_user(app) as client:
            r = client.get("/teams/new")
            assert r.status_code == 403

            # team should be blocked from creation
            with client.session_transaction() as sess:
                data = {
                    "name": "team1",
                    "password": "******",
                    "nonce": sess.get("nonce"),
                }
            r = client.post("/teams/new", data=data)
            resp = r.get_data(as_text=True)
            assert Teams.query.count() == 1
            assert "Reached the maximum number of teams" in resp

            # Can the team be created after the num has been bumped
            set_config("num_teams", 2)
            r = client.post("/teams/new", data=data)
            resp = r.get_data(as_text=True)
            assert Teams.query.count() == 2
    destroy_ctfd(app)
Example #3
0
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)
Example #4
0
def test_api_team_patch_non_admin():
    """Can a user patch /api/v1/teams/<team_id> if not admin"""
    app = create_kmactf(user_mode="teams")
    with app.app_context():
        gen_team(app.db)
        with app.test_client() as client:
            r = client.patch("/api/v1/teams/1", json="")
            assert r.status_code == 403
    destroy_kmactf(app)
Example #5
0
def test_api_team_delete_non_admin():
    """Can a user delete /api/v1/teams/<team_id> if not admin"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        gen_team(app.db)
        with app.test_client() as client:
            r = client.delete('/api/v1/teams/1', json="")
            assert r.status_code == 403
    destroy_ctfd(app)
Example #6
0
def test_api_accessing_hidden_banned_users():
    """Hidden/Banned users should not be visible to normal users, only to admins"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        register_user(app)
        register_user(app, name="user2", email="*****@*****.**")
        register_user(app, name="visible_user", email="*****@*****.**")

        user = Users.query.filter_by(id=2).first()
        team = gen_team(app.db,
                        name="hidden_team",
                        email="*****@*****.**",
                        hidden=True)
        team.members.append(user)
        user.team_id = team.id
        app.db.session.commit()

        user = Users.query.filter_by(id=3).first()
        team = gen_team(app.db,
                        name="banned_team",
                        email="*****@*****.**",
                        banned=True)
        team.members.append(user)
        user.team_id = team.id
        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
            assert client.get("/api/v1/teams/1/awards").status_code == 404

            assert client.get("/api/v1/teams/2").status_code == 404
            assert client.get("/api/v1/teams/2/solves").status_code == 404
            assert client.get("/api/v1/teams/2/fails").status_code == 404
            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
            assert client.get("/api/v1/teams/1/awards").status_code == 200

            assert client.get("/api/v1/teams/2").status_code == 200
            assert client.get("/api/v1/teams/2/solves").status_code == 200
            assert client.get("/api/v1/teams/2/fails").status_code == 200
            assert client.get("/api/v1/teams/2/awards").status_code == 200
    destroy_ctfd(app)
Example #7
0
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)
        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
    destroy_ctfd(app)
Example #8
0
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)
Example #9
0
def test_admin_access():
    """Can a user access admin pages?"""
    app = create_ctfd()
    with app.app_context():
        gen_page(app.db, title="title", route="/route", content="content")
        gen_challenge(app.db)
        gen_team(app.db)
        routes = [
            "/admin/challenges/new",
            "/admin/export/csv",
            # '/admin/pages/preview',
            "/admin/pages/new",
            "/admin/teams/new",
            "/admin/users/new",
            "/admin/notifications",
            "/admin/challenges",
            "/admin/scoreboard",
            "/admin/statistics",
            "/admin/export",
            "/admin/config",
            "/admin/pages",
            "/admin/teams",
            "/admin/users",
            "/admin",
            "/admin/submissions/correct",
            "/admin/submissions/incorrect",
            "/admin/submissions",
            "/admin/challenges/1",
            # '/admin/plugins/<plugin>',
            "/admin/pages/1",
            "/admin/teams/1",
            "/admin/users/1",
        ]
        register_user(app)
        client = login_as_user(app)

        for route in routes:
            r = client.get(route)
            assert r.status_code == 302
            assert r.location.startswith("http://localhost/login")

        admin = login_as_user(app, name="admin")
        routes.remove("/admin")
        routes.remove("/admin/export/csv")
        routes.remove("/admin/export")
        for route in routes:
            r = admin.get(route)
            assert r.status_code == 200
    destroy_ctfd(app)
Example #10
0
def test_teams_dont_prevent_other_teams_from_unlocking_hints():
    """Unlocks from one user don't affect other users"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        chal = gen_challenge(app.db)
        gen_hint(app.db,
                 chal.id,
                 content="This is a hint",
                 cost=1,
                 type="standard")

        team1 = gen_team(app.db, name="team1", email="*****@*****.**")
        team2 = gen_team(app.db, name="team2", email="*****@*****.**")

        # Give users points with an award
        gen_award(app.db, user_id=team1.captain_id)
        gen_award(app.db, user_id=team2.captain_id)

        captain1 = team1.captain.name
        captain2 = team2.captain.name

        app.db.session.commit()

        # First team unlocks hint
        with login_as_user(app, name=captain1) as client:
            r = client.get("/api/v1/hints/1")
            assert r.status_code == 200
            r = client.post("/api/v1/unlocks",
                            json={
                                "target": 1,
                                "type": "hints"
                            })
            assert r.status_code == 200
            r = client.get("/api/v1/hints/1")
            assert r.status_code == 200

        # Second team unlocks hint
        with login_as_user(app, name=captain2) as client:
            r = client.get("/api/v1/hints/1")
            assert r.status_code == 200
            r = client.post("/api/v1/unlocks",
                            json={
                                "target": 1,
                                "type": "hints"
                            })
            assert r.status_code == 200
            r = client.get("/api/v1/hints/1")
            assert r.status_code == 200
    destroy_ctfd(app)
Example #11
0
def test_api_user_patch_team_id():
    """Users can't patch their team_id directly"""
    app = create_ctfd()
    with app.app_context():
        register_user(app)
        gen_team(app.db)

        with login_as_user(app) as client:
            data = {
                "team_id": 1,
            }
            r = client.patch("/api/v1/users/me", json=data)
            data = r.get_json()
            assert data["data"]["team_id"] is None
    destroy_ctfd(app)
Example #12
0
def test_team_size_limit():
    """Only team_size amount of members can join a team even via MLC"""
    app = create_kmactf(user_mode="teams")
    app.config.update({
        "OAUTH_CLIENT_ID": "kmactf_testing_client_id",
        "OAUTH_CLIENT_SECRET": "kmactf_testing_client_secret",
        "OAUTH_AUTHORIZATION_ENDPOINT":
        "http://auth.localhost/oauth/authorize",
        "OAUTH_TOKEN_ENDPOINT": "http://auth.localhost/oauth/token",
        "OAUTH_API_ENDPOINT": "http://api.localhost/user",
    })
    with app.app_context():
        set_config("team_size", 1)
        team = gen_team(app.db, member_count=1, oauth_id=1234)
        team_id = team.id
        login_with_mlc(app,
                       team_name="team_name",
                       team_oauth_id=1234,
                       raise_for_error=False)
        assert len(Teams.query.filter_by(id=team_id).first().members) == 1

        set_config("team_size", 2)
        login_with_mlc(app, team_name="team_name", team_oauth_id=1234)
        assert len(Teams.query.filter_by(id=team_id).first().members) == 2
    destroy_kmactf(app)
Example #13
0
def test_api_team_get_public():
    """Can a user get /api/v1/team/<team_id> if teams are public"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        with app.test_client() as client:
            set_config('account_visibility', 'public')
            gen_team(app.db)
            r = client.get('/api/v1/teams/1')
            assert r.status_code == 200
            set_config('account_visibility', 'private')
            r = client.get('/api/v1/teams/1')
            assert r.status_code == 302
            set_config('account_visibility', 'admins')
            r = client.get('/api/v1/teams/1')
            assert r.status_code == 404
    destroy_ctfd(app)
Example #14
0
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)
Example #15
0
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)
Example #16
0
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)
Example #17
0
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_removing_members_deletes_information():
    """If an admin removes a user, their score information should also be removed"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        team = gen_team(app.db)
        assert len(team.members) == 4
        app.db.session.commit()

        user = Users.query.filter_by(id=2).first()
        simulate_user_activity(app.db, user)
        assert Solves.query.filter_by(user_id=2).count() == 1
        assert Submissions.query.filter_by(user_id=2).count() == 6
        assert Awards.query.filter_by(user_id=2).count() == 1
        assert Unlocks.query.filter_by(user_id=2).count() == 1

        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

        user = Users.query.filter_by(id=2).first()
        assert Solves.query.filter_by(user_id=2).count() == 0
        assert Submissions.query.filter_by(user_id=2).count() == 0
        assert Awards.query.filter_by(user_id=2).count() == 0
        assert Unlocks.query.filter_by(user_id=2).count() == 0
    destroy_ctfd(app)
Example #19
0
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)
Example #20
0
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)
Example #21
0
def test_api_team_get_admin():
    """Can a user get /api/v1/teams/<team_id> if teams are viewed by admins only"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        with login_as_user(app, 'admin') as client:
            gen_team(app.db)
            set_config('account_visibility', 'public')
            r = client.get('/api/v1/teams/1')
            assert r.status_code == 200
            set_config('account_visibility', 'private')
            r = client.get('/api/v1/teams/1')
            assert r.status_code == 200
            set_config('account_visibility', 'admins')
            r = client.get('/api/v1/teams/1')
            assert r.status_code == 200
    destroy_ctfd(app)
Example #22
0
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)
Example #23
0
def test_team_size_limit():
    """Only team_size amount of members can join a team"""
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        set_config("team_size", 1)

        # Create a team with only one member
        team = gen_team(app.db, member_count=1)
        team_id = team.id

        register_user(app)
        with login_as_user(app) as client:
            r = client.get("/teams/join")
            assert r.status_code == 200

            # User should be blocked from joining
            with client.session_transaction() as sess:
                data = {
                    "name": "team_name",
                    "password": "******",
                    "nonce": sess.get("nonce"),
                }
            r = client.post("/teams/join", data=data)
            resp = r.get_data(as_text=True)
            assert len(Teams.query.filter_by(id=team_id).first().members) == 1
            assert "already reached the team size limit of 1" in resp

            # Can the user join after the size has been bumped
            set_config("team_size", 2)
            r = client.post("/teams/join", data=data)
            resp = r.get_data(as_text=True)
            assert len(Teams.query.filter_by(id=team_id).first().members) == 2
    destroy_ctfd(app)
Example #24
0
def test_api_team_get_admin():
    """Can a user get /api/v1/teams/<team_id> if teams are viewed by admins only"""
    app = create_kmactf(user_mode="teams")
    with app.app_context():
        with login_as_user(app, "admin") as client:
            gen_team(app.db)
            set_config("account_visibility", "public")
            r = client.get("/api/v1/teams/1")
            assert r.status_code == 200
            set_config("account_visibility", "private")
            r = client.get("/api/v1/teams/1")
            assert r.status_code == 200
            set_config("account_visibility", "admins")
            r = client.get("/api/v1/teams/1")
            assert r.status_code == 200
    destroy_kmactf(app)
Example #25
0
def test_team_invite_codes():
    app = create_ctfd(user_mode="teams")
    with app.app_context():
        team1 = gen_team(app.db, name="team1", email="*****@*****.**")
        with freeze_time("2017-10-7 00:00:00"):
            invite_code = team1.get_invite_code()
            team = Teams.load_invite_code(invite_code)
            assert team.id == team1.id

        with freeze_time("2017-10-8 00:00:01"):
            try:
                team = Teams.load_invite_code(invite_code)
            except TeamTokenExpiredException:
                # This token should be expired and we shouldn't get a team object back
                pass
            else:
                print("Token should have expired")
                raise Exception

        # Change team's password
        team.password = "******"
        app.db.session.commit()

        with freeze_time("2017-10-7 00:00:00"):
            try:
                team = Teams.load_invite_code(invite_code)
            except TeamTokenInvalidException:
                pass
            else:
                print("Token should have been invalidated by password change")
                raise Exception
    destroy_ctfd(app)
Example #26
0
def test_api_team_get_public():
    """Can a user get /api/v1/team/<team_id> if teams are public"""
    app = create_kmactf(user_mode="teams")
    with app.app_context():
        with app.test_client() as client:
            set_config("account_visibility", "public")
            gen_team(app.db)
            r = client.get("/api/v1/teams/1")
            assert r.status_code == 200
            set_config("account_visibility", "private")
            r = client.get("/api/v1/teams/1")
            assert r.status_code == 302
            set_config("account_visibility", "admins")
            r = client.get("/api/v1/teams/1")
            assert r.status_code == 404
    destroy_kmactf(app)
Example #27
0
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)
Example #28
0
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)
Example #29
0
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)
Example #30
0
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)