Esempio n. 1
0
def register_administrator():
    """Register a new user"""
    body = flask_rebar.get_validated_body()
    email = body["email"]
    username = body["username"]
    password = body["password"]

    # Validate user uniqueness constraint.
    user = User.query.filter_by(email=email).first()
    if user is not None:
        administrator = user.get_administrator()

        if administrator is not None:
            raise errors.UnprocessableEntity("An administrator with that email already exists")

    user = User.query.filter_by(username=username).first()
    if user is not None:
        administrator = user.get_administrator()

        if administrator:
            raise errors.UnprocessableEntity("An administrator with that username already exists for this event")

    user = User(email=email, username=username)
    user.set_password(password)

    administrator = Administrator(is_platform_admin=False, user=user)

    DB.session.add(administrator)
    DB.session.commit()

    return administrator, 201
Esempio n. 2
0
File: teams.py Progetto: JDIS/flaggr
def create_team(current_participant: Participant):
    """Create a team for a given event."""
    body = flask_rebar.get_validated_body()
    team_name = body["team_name"]

    if not team_name:
        raise errors.UnprocessableEntity("Please choose a team name")

    team = current_participant.get_team()

    if team is not None:
        raise errors.UnprocessableEntity(
            "You cannot create a team if you already are in a team.")

    team = Team.query.filter_by(name=team_name).first()

    if team is not None:
        raise errors.UnprocessableEntity(
            "A team with that name already exists.")

    team = Team(name=team_name,
                event_id=current_participant.event_id,
                members=[
                    TeamMember(participant_id=current_participant.id,
                               captain=True)
                ])

    DB.session.add(team)
    DB.session.commit()
    return team
Esempio n. 3
0
File: teams.py Progetto: JDIS/flaggr
def send_team_request(current_participant: Participant):
    """Request to join a team."""
    body = flask_rebar.get_validated_body()
    team_id = body["team_id"]

    team_member = current_participant.get_team()

    if team_member is not None:
        raise errors.UnprocessableEntity(
            "You cannot request to join a team if you already are in a team.")

    team = Team.query.filter_by(id=team_id).first()

    if team is None:
        raise errors.UnprocessableEntity("The team doesn't exist.")

    # FIXMEFUTURE: If team is not already full
    # (on a pas de configuration pour le nombre de membres d'une équipe for now)
    team_request = TeamRequest.query.filter_by(
        participant_id=current_participant.id).first()

    if team_request is not None:
        raise errors.UnprocessableEntity(
            "You already have requested to join a team.")

    team_request = TeamRequest(team_id=team_id,
                               participant_id=current_participant.id)

    DB.session.add(team_request)
    DB.session.commit()
    return ""
Esempio n. 4
0
def edit_challenge(current_admin: Administrator, challenge_id: int):
    """Edit a challenge and its associated ressources (flags, links, files)"""
    body = flask_rebar.get_validated_body()
    name = body["name"]
    points = body["points"]
    hidden = body["hidden"]
    description = body["description"]
    category_id = body["category_id"]
    flags = body["flags"]

    editable_challenge = Challenge.query.filter_by(id=challenge_id).first()

    if editable_challenge is None:
        raise errors.UnprocessableEntity("This challenge does not exist.")

    if not current_admin.is_admin_of_event(
            editable_challenge.category.event_id):
        raise errors.Unauthorized(
            "You do not have the permission to administer this challenge.")

    if category_id != editable_challenge.category_id:
        category = Category.query.filter_by(
            id=category_id,
            event_id=editable_challenge.category.event_id).first()

        if category is None:
            raise errors.UnprocessableEntity("The category doesn't exist.")

    if name != editable_challenge.name:
        if not name:
            raise errors.UnprocessableEntity("Name must not be empty.")

        challenge = Challenge.query.filter_by(name=name).first()

        if challenge is not None:
            raise errors.UnprocessableEntity(
                "A challenge with that name already exists.")

    if points != editable_challenge.points and points <= 0:
        raise errors.UnprocessableEntity("Points must be positive.")

    editable_challenge.name = name
    editable_challenge.points = points
    editable_challenge.hidden = hidden
    editable_challenge.description = description
    editable_challenge.category_id = category_id
    flag_objects = list(
        map(lambda flag: Flag(is_regex=flag['is_regex'], value=flag['value']),
            flags))
    editable_challenge.flags = flag_objects

    DB.session.commit()

    return editable_challenge
Esempio n. 5
0
def create_event(current_admin: Administrator):
    """Create a new event"""
    # pylint: disable=unused-argument
    body = flask_rebar.get_validated_body()
    name = body["name"]
    teams = body["teams"]
    is_open = body["is_open"]
    is_visible = body["is_visible"]
    front_page = body["front_page"] if "front_page" in body else ""
    flag_format = body["flag_format"] if "flag_format" in body else ""

    event = Event.query.filter_by(name=name).first()

    if event:
        raise errors.UnprocessableEntity(
            "An event with that name already exists")

    event = Event(name=name,
                  front_page=front_page,
                  flag_format=flag_format,
                  is_open=is_open,
                  is_visible=is_visible,
                  teams=teams)

    DB.session.add(event)
    DB.session.commit()

    return event
Esempio n. 6
0
def create_category(current_admin: Administrator):
    """Add a category """
    body = flask_rebar.get_validated_body()
    name = body["name"]
    event_id = body["event_id"]

    event = Event.query.filter_by(id=event_id).first()

    if event is None:
        raise errors.NotFound(f'Event with id "{event_id}" not found.')

    if not current_admin.is_admin_of_event(event_id):
        raise errors.Unauthorized(
            "You do not have the permission to administer this event.")

    category = Category.query.filter_by(name=name, event_id=event_id).first()

    if category is not None:
        raise errors.UnprocessableEntity(
            "A category with that name already exists")

    category = Category(name=name, event_id=event_id)

    DB.session.add(category)
    DB.session.commit()

    return category
Esempio n. 7
0
File: teams.py Progetto: JDIS/flaggr
def accept_team_request(current_participant: Participant):
    """Accepts a team request. Only captains can accept a request."""
    body = flask_rebar.get_validated_body()
    participant_id = body["participant_id"]

    current_member = TeamMember.query.filter_by(
        participant_id=current_participant.id).first()

    if not current_member or not current_member.captain:
        raise errors.Unauthorized(
            "You don't have the rights to accept this request.")

    # Remove TeamRequest and add the new member
    team_request = TeamRequest.query.filter_by(
        team_id=current_member.team_id, participant_id=participant_id).first()

    if team_request is None:
        raise errors.UnprocessableEntity("The request doesn't exist.")

    new_member = TeamMember(participant_id=participant_id,
                            team_id=current_member.team_id)

    DB.session.delete(team_request)
    DB.session.add(new_member)
    DB.session.commit()

    return ""
Esempio n. 8
0
def submit_flag(challenge: Challenge, event: Event):
    """Submit a flag for a given challenge"""

    body = flask_rebar.get_validated_body()
    submitted_flag = body["flag"]

    team = current_user.get_team()

    if team is None:
        raise errors.NotFound(f'Current user has no team.')

    if event.id != team.event_id:
        raise errors.UnprocessableEntity(
            f'Team "{team.name}" and challenge "{challenge.id}" are not part of the same event')

    submission = Submission(team_id=team.id, challenge_id=challenge.id, input=submitted_flag)

    flags = Flag.query.filter_by(challenge_id=challenge.id).all()

    is_correct = any(validate_flag(x, submitted_flag) for x in flags)
    submission.is_correct = is_correct

    DB.session.add(submission)
    DB.session.commit()

    return {'correct': is_correct}
Esempio n. 9
0
File: auth.py Progetto: JDIS/flaggr
def register_participant(event: Event):
    """Register a new user"""
    body = flask_rebar.get_validated_body()
    email = body["email"]
    username = body["username"]
    password = body["password"]

    if not username:
        raise errors.UnprocessableEntity("Please choose a username")

    # Validate user uniqueness constraint.
    user = User.query.filter_by(email=email).first()
    if user is not None:
        participant = user.get_participant()

        if user is not None and participant and participant.event_id == event.id:
            raise errors.UnprocessableEntity("A participant with that email already exists for this event")

    user = User.query.filter_by(username=username).first()
    if user is not None:
        participant = user.get_participant()

        if user is not None and participant and participant.event_id == event.id:
            raise errors.UnprocessableEntity("A participant with that username already exists for this event")

    user = User(email=email, username=username)
    user.set_password(password)

    participant = Participant(event_id=event.id, user=user)

    DB.session.add(participant)

    if not event.teams:
        # means that its a solo event, need to create a team with the participant in it.
        team = Team(event_id=event.id, name=user.username,
                    members=[TeamMember(participant=participant, captain=True)])

        DB.session.add(team)

    DB.session.commit()

    login_user(participant.user, remember=True)

    return participant, 201
Esempio n. 10
0
File: teams.py Progetto: JDIS/flaggr
def leave_team(current_participant: Participant):
    """Leave a team"""
    # NOTE: When the last member of a team leaves, what should happen? We do not want to delete a team.

    team_member = TeamMember.query.filter_by(
        participant_id=current_participant.id).first()

    if team_member is None:
        raise errors.UnprocessableEntity("You are not in a team.")

    DB.session.delete(team_member)
    DB.session.commit()
    return ""
Esempio n. 11
0
File: teams.py Progetto: JDIS/flaggr
def remove_own_team_request(current_participant: Participant):
    """Remove own request."""

    team_request = TeamRequest.query.filter_by(
        participant_id=current_participant.id).first()

    if team_request is None:
        raise errors.UnprocessableEntity(
            "You don't have any pending requests.")

    DB.session.delete(team_request)
    DB.session.commit()
    return ""
Esempio n. 12
0
def edit_event(current_admin: Administrator, event_id: int):
    """Edit an new event"""
    # pylint: disable=unused-argument
    body = flask_rebar.get_validated_body()
    name = body["name"]
    teams = body["teams"]
    is_open = body["is_open"]
    is_visible = body["is_visible"]
    front_page = body["front_page"] if "front_page" in body else ""
    flag_format = body["flag_format"] if "flag_format" in body else ""

    editable_event = Event.query.filter_by(id=event_id).first()

    if editable_event is None:
        raise errors.NotFound(f'Event with id "{event_id}" not found.')

    if name != editable_event.name:
        if not name:
            raise errors.UnprocessableEntity("Name must not be empty.")

        event = Event.query.filter_by(name=name).first()

        if event is not None:
            raise errors.UnprocessableEntity(
                "An event with that name already exists.")

    editable_event.name = name
    editable_event.front_page = front_page
    editable_event.flag_format = flag_format
    editable_event.is_open = is_open
    editable_event.is_visible = is_visible
    editable_event.teams = teams

    DB.session.commit()

    return editable_event
Esempio n. 13
0
def make_challenge_hidden(current_admin: Administrator, challenge_id: int):
    """Make a challenge hidden"""

    challenge = Challenge.query.filter_by(id=challenge_id).first()

    if challenge is None:
        raise errors.UnprocessableEntity("This challenge does not exist.")

    if not current_admin.is_admin_of_event(challenge.category.event_id):
        raise errors.Unauthorized(
            "You do not have the permission to administer this challenge.")

    challenge.hidden = True

    DB.session.commit()

    return {"name": "OK"}
Esempio n. 14
0
def login_administrator():
    """Login an administrator"""

    body = flask_rebar.get_validated_body()
    email = body["email"]
    password = body["password"]
    remember = body["remember"] if "remember" in body else False

    user = User.query.filter_by(email=email).first()
    if user is None or not user.check_password(password):
        raise errors.UnprocessableEntity("Invalid email or password.")

    administrator = user.get_administrator()
    if administrator is None:
        raise errors.Unauthorized("You must be an administrator to access this resource.")

    login_user(user, remember=remember)

    return administrator
Esempio n. 15
0
File: auth.py Progetto: JDIS/flaggr
def login(event: Event):
    """Login a participant"""

    body = flask_rebar.get_validated_body()
    email = body["email"]
    password = body["password"]
    remember = body["remember"]

    participant = Participant.query\
        .join(Participant.user) \
        .filter(User.email == email,
                Participant.event_id == event.id)\
        .first()

    if participant is None or participant.user is None or not participant.user.check_password(password):
        raise errors.UnprocessableEntity("Invalid email or password.")

    login_user(participant.user, remember=remember)

    return participant
Esempio n. 16
0
File: teams.py Progetto: JDIS/flaggr
def kick_team_member(current_participant: Participant):
    """Kick a member of the team. Only captains can kick a team member"""
    body = flask_rebar.get_validated_body()
    participant_id = body["participant_id"]
    current_member = TeamMember.query.filter_by(
        participant_id=current_participant.id).first()

    if not current_member or not current_member.captain:
        raise errors.Unauthorized(
            "You don't have the rights to kick a team member.")

    if participant_id == current_participant.id:
        raise errors.UnprocessableEntity(
            "You cannot kick yourself from a team.")

    team_member = TeamMember.query.filter_by(
        participant_id=participant_id).first()

    DB.session.delete(team_member)
    DB.session.commit()
    return ""
Esempio n. 17
0
def delete_challenge(current_admin: Administrator, challenge_id: int):
    """Delete a challenge"""

    challenge = Challenge.query.filter_by(id=challenge_id).first()

    if challenge is None:
        raise errors.UnprocessableEntity("This challenge does not exist.")

    if not current_admin.is_admin_of_event(challenge.category.event_id):
        raise errors.Unauthorized(
            "You do not have the permission to administer this challenge.")

    # Cleanup associated ressources
    flags = Flag.query.filter_by(challenge_id=challenge_id).all()
    submissions = Submission.query.filter_by(challenge_id=challenge_id).all()

    DB.session.delete(challenge)
    for flag in flags:
        DB.session.delete(flag)
    for submission in submissions:
        DB.session.delete(submission)
    DB.session.commit()

    return ""
Esempio n. 18
0
File: teams.py Progetto: JDIS/flaggr
def change_role(current_participant: Participant):
    """Change the role of a team member. Only captains can change a team member's role"""
    body = flask_rebar.get_validated_body()
    participant_id = body["participant_id"]
    new_role = body["captain"]

    current_member = TeamMember.query.filter_by(
        participant_id=current_participant.id).first()

    if not current_member or not current_member.captain:
        raise errors.Unauthorized(
            "You don't have the rights to change a team member's role.")

    if participant_id == current_participant.id:
        # In order to avoid a team "bricking" itself
        raise errors.UnprocessableEntity(
            "You cannot remove your own privileges.")

    team_member = TeamMember.query.filter_by(
        participant_id=participant_id).first()
    team_member.captain = new_role

    DB.session.commit()
    return ""