Пример #1
0
def new():
    infos = get_infos()
    errors = get_errors()
    if request.method == "GET":
        team_size_limit = get_config("team_size", default=0)
        if team_size_limit:
            plural = "" if team_size_limit == 1 else "s"
            infos.append("Teams are limited to {limit} member{plural}".format(
                limit=team_size_limit, plural=plural))

        return render_template("teams/new_team.html",
                               infos=infos,
                               errors=errors)
    elif request.method == "POST":
        teamname = request.form.get("name", "").strip()
        passphrase = request.form.get("password", "").strip()
        errors = get_errors()

        website = request.form.get("website")
        affiliation = request.form.get("affiliation")

        user = get_current_user()

        existing_team = Teams.query.filter_by(name=teamname).first()
        if existing_team:
            errors.append("Такое имя команды уже занято")
        if not teamname:
            errors.append("Имя команды неправильное")

        # Process additional user fields
        fields = {}
        for field in TeamFields.query.all():
            fields[field.id] = field

        entries = {}
        for field_id, field in fields.items():
            value = request.form.get(f"fields[{field_id}]", "").strip()
            if field.required is True and (value is None or value == ""):
                errors.append("Пожалуйста, укажите все обязательные поля")
                break

            # Handle special casing of existing profile fields
            if field.name.lower() == "affiliation":
                affiliation = value
                break
            elif field.name.lower() == "website":
                website = value
                break

            if field.field_type == "boolean":
                entries[field_id] = bool(value)
            else:
                entries[field_id] = value

        if website:
            valid_website = validators.validate_url(website)
        else:
            valid_website = True

        if affiliation:
            valid_affiliation = len(affiliation) < 128
        else:
            valid_affiliation = True

        if valid_website is False:
            errors.append(
                "Вебсайт должен быть правильной ссылкой, начинающейся с http или https"
            )
        if valid_affiliation is False:
            errors.append("Пожалуйста, укажите учреждение покороче")

        if errors:
            return render_template("teams/new_team.html", errors=errors)

        team = Teams(name=teamname, password=passphrase, captain_id=user.id)

        if website:
            team.website = website
        if affiliation:
            team.affiliation = affiliation

        db.session.add(team)
        db.session.commit()

        for field_id, value in entries.items():
            entry = TeamFieldEntries(field_id=field_id,
                                     value=value,
                                     team_id=team.id)
            db.session.add(entry)
        db.session.commit()

        user.team_id = team.id
        db.session.commit()

        clear_user_session(user_id=user.id)
        clear_team_session(team_id=team.id)

        return redirect(url_for("challenges.listing"))
Пример #2
0
def new():
    infos = get_infos()
    errors = get_errors()

    if bool(get_config("team_creation", default=True)) is False:
        abort(
            403,
            description="Team creation is currently disabled. Please join an existing team.",
        )

    num_teams_limit = int(get_config("num_teams", default=0))
    num_teams = Teams.query.filter_by(banned=False, hidden=False).count()
    if num_teams_limit and num_teams >= num_teams_limit:
        abort(
            403,
            description=f"Reached the maximum number of teams ({num_teams_limit}). Please join an existing team.",
        )

    user = get_current_user_attrs()
    if user.team_id:
        errors.append("You are already in a team. You cannot join another.")

    if request.method == "GET":
        team_size_limit = get_config("team_size", default=0)
        if team_size_limit:
            plural = "" if team_size_limit == 1 else "s"
            infos.append(
                "Teams are limited to {limit} member{plural}".format(
                    limit=team_size_limit, plural=plural
                )
            )
        return render_template("teams/new_team.html", infos=infos, errors=errors)

    elif request.method == "POST":
        teamname = request.form.get("name", "").strip()
        passphrase = request.form.get("password", "").strip()

        website = request.form.get("website")
        affiliation = request.form.get("affiliation")

        user = get_current_user()

        existing_team = Teams.query.filter_by(name=teamname).first()
        if existing_team:
            errors.append("That team name is already taken")
        if not teamname:
            errors.append("That team name is invalid")

        # Process additional user fields
        fields = {}
        for field in TeamFields.query.all():
            fields[field.id] = field

        entries = {}
        for field_id, field in fields.items():
            value = request.form.get(f"fields[{field_id}]", "").strip()
            if field.required is True and (value is None or value == ""):
                errors.append("Please provide all required fields")
                break

            # Handle special casing of existing profile fields
            if field.name.lower() == "affiliation":
                affiliation = value
                break
            elif field.name.lower() == "website":
                website = value
                break

            if field.field_type == "boolean":
                entries[field_id] = bool(value)
            else:
                entries[field_id] = value

        if website:
            valid_website = validators.validate_url(website)
        else:
            valid_website = True

        if affiliation:
            valid_affiliation = len(affiliation) < 128
        else:
            valid_affiliation = True

        if valid_website is False:
            errors.append("Websites must be a proper URL starting with http or https")
        if valid_affiliation is False:
            errors.append("Please provide a shorter affiliation")

        if errors:
            return render_template("teams/new_team.html", errors=errors), 403

        team = Teams(name=teamname, password=passphrase, captain_id=user.id)

        if website:
            team.website = website
        if affiliation:
            team.affiliation = affiliation

        db.session.add(team)
        db.session.commit()

        for field_id, value in entries.items():
            entry = TeamFieldEntries(field_id=field_id, value=value, team_id=team.id)
            db.session.add(entry)
        db.session.commit()

        user.team_id = team.id
        db.session.commit()

        clear_user_session(user_id=user.id)
        clear_team_session(team_id=team.id)

        return redirect(url_for("challenges.listing"))
Пример #3
0
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)