Esempio n. 1
0
def create_new_category():
    """
    Create a new category given parameters in application/json body
    """
    data = request.get_json()

    check_existing_category = Category.query.filter_by(name=data['name'].lower()).first()
    if check_existing_category:
        return collision()

    upload_required = bool(data.get("upload_required"))

    new_category = Category.create(data['name'].lower(), data['description'], upload_required)
    return jsonify(new_category), 201
Esempio n. 2
0
def create_difficulty():
    """
    Creates a difficulty

    Takes 'name' value from application/json body and creates a Difficulty
    """
    data = request.get_json()

    check_difficulty = Difficulty.query.filter_by(name=data['name'].lower()).first()
    if check_difficulty:
        return collision()

    new_difficulty = Difficulty.create(data['name'].lower())
    return jsonify(new_difficulty), 201
Esempio n. 3
0
def purchase_hint(challenge_id: int = 0, flag_id: int = 0, hint_id: int = 0, **kwargs):
    # pylint: disable=unused-argument
    """
    Operations relating to used hints

    :POST: Allow a user to pay for a hint
    """
    hint = Hint.query.filter_by(id=hint_id).first()
    if not hint:
        return not_found()

    current_username = kwargs['userinfo'].get('preferred_username')
    if not current_username:
        return no_username()

    # Check that the relation doesn't already exist
    used_hints_check = UsedHint.query.filter_by(hint_id=hint_id, username=current_username).first()
    if used_hints_check:
        return collision()

    if current_username == hint.flag.challenge.submitter:
        return jsonify({
            'status': "error",
            'message': "You created this hint!"
        }), 403

    if Solved.query.filter_by(flag_id=hint.flag.id).first():
        return jsonify({
            'status': "error",
            'message': "You already solved the flag associated with this hint!"
        }), 422

    if get_user_score(current_username)[0] - hint.cost < 0:
        return jsonify({
            'status': "error",
            'message': "You don't have enough points to purchase this hint!"
        }), 422

    new_used_hint = UsedHint.create(hint_id, current_username)
    return jsonify(new_used_hint.hint.to_dict()), 201
Esempio n. 4
0
def single_tag(challenge_id: int, tag_name: str, **kwargs):
    """
    Creates a tag
    """
    challenge = Challenge.query.filter_by(id=challenge_id).first()
    if not challenge:
        return not_found()

    tag = ChallengeTag.query.filter_by(tag=tag_name, challenge_id=challenge_id).first()

    if tag:
        return collision()

    current_username = kwargs['userinfo'].get('preferred_username')
    if not current_username:
        return no_username()
    groups = kwargs['userinfo'].get('groups')
    if current_username != challenge.submitter and not is_ctf_admin(groups):
        return not_authorized()

    new_tag = ChallengeTag.create(challenge_id, tag_name)
    return jsonify(new_tag), 201
Esempio n. 5
0
def create_challenge(**kwargs):
    """
    Creates a challenge given parameters in application/json body
    """
    data = request.form.to_dict()
    category = Category.query.filter_by(name=data['category'].lower()).first()
    difficulty = Difficulty.query.filter_by(name=data['difficulty'].lower()).first()

    if not (category and difficulty):
        return jsonify({
            'status': "error",
            'message': "The category or difficulty doesn't exist"
        }), 422

    submitter = kwargs['userinfo'].get('preferred_username')
    if not submitter:
        return no_username()

    # check if challenge with matching title already exists
    if Challenge.query.filter(Challenge.title.ilike('test')).first():
        return collision()

    file = request.files.get('file')
    if category.upload_required and not file:
        return missing_body_parts("multipart/form-data", "file")
    else:
        split = os.path.splitext(secure_filename(file.filename))
        filename = secure_filename(data['title'] + str(split[-1]))
        filepath = os.path.join(app.config['UPLOAD_PATH'], filename)
        file.save(filepath)

    mime = magic.Magic(mime=True)
    if not mime.from_file(filepath) in app.config['ALLOWED_MIME_TYPES']:
        return invalid_mime_type(mime.from_file(filepath))

    tags = []
    if tag_names := data.get('tags'):
        tags = list(dict.fromkeys(tag_names.split(",")))
Esempio n. 6
0
def add_flag(challenge_id: int, **kwargs):
    """
    Create a flag given parameters in application/json body
    """
    challenge = Challenge.query.filter_by(id=challenge_id).first()
    if not challenge:
        return not_found()

    data = request.get_json()
    flag_exists = Flag.query.filter_by(challenge_id=challenge_id,
                                       flag=data['flag']).first()
    if flag_exists:
        return collision()

    current_username = kwargs['userinfo'].get('preferred_username')
    if not current_username:
        return no_username()
    groups = kwargs['userinfo'].get('groups')
    if current_username != challenge.submitter and not is_ctf_admin(groups):
        return not_authorized()

    new_flag = Flag.create(data['point_value'], data['flag'], challenge_id)
    return jsonify(new_flag), 201
Esempio n. 7
0
def solve_flag(challenge_id: int, **kwargs):
    """
    Operations pertaining to the solved relations on a challenge (but really a flag).

    :param challenge_id: The challenge that a solution is being attempted on

    :POST: Attempt solution of all flags associated with this challenge
    """
    challenge = Challenge.query.filter_by(id=challenge_id).first()
    if not challenge:
        return not_found()

    data = request.get_json()
    flag_attempt = data['flag']
    flags = Flag.query.filter_by(challenge_id=challenge_id).all()

    current_username = kwargs['userinfo'].get('preferred_username')
    if not current_username:
        return no_username()

    if challenge.submitter == current_username:
        return jsonify({
            'status': "error",
            'message': "You created this flag!"
        }), 403

    for flag in flags:
        if flag.flag == flag_attempt:
            check_solved = Solved.query.filter_by(
                flag_id=flag.id, username=current_username).first()
            if check_solved:
                return collision()

            Solved.create(flag.id, current_username)
            return jsonify(challenge.to_dict()), 201
    return jsonify({'status': "error", 'message': "Incorrect flag"}), 400