12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- from flask import request, redirect, abort, jsonify, url_for
- from CTFd.models import db, Solves, Challenges, WrongKeys, Keys, Tags, Files
- from CTFd import utils
- import os
- import boto3
- import hashlib
- import string
- from werkzeug.utils import secure_filename
- def clean_filename(c):
- if c in string.ascii_letters + string.digits + '-' + '_' + '.':
- return True
- def get_s3_conn(app):
- access_key_id = utils.get_app_config('ACCESS_KEY_ID')
- secret_access_key = utils.get_app_config('SECRET_ACCESS_KEY')
- if access_key_id and secret_access_key:
- client = boto3.client(
- 's3',
- aws_access_key_id=access_key_id,
- aws_secret_access_key=secret_access_key
- )
- bucket = utils.get_app_config('BUCKET')
- return client, bucket
- else:
- client = boto3.client('s3')
- bucket = utils.get_app_config('BUCKET')
- return client, bucket
- def load(app):
- def upload_file(file, chalid):
- s3, bucket = get_s3_conn(app)
- filename = filter(clean_filename, secure_filename(file.filename).replace(' ', '_'))
- if len(filename) <= 0:
- return False
- md5hash = hashlib.md5(os.urandom(64)).hexdigest()
- key = md5hash + '/' + filename
- s3.upload_fileobj(file, bucket, key)
- db_f = Files(chalid, key)
- db.session.add(db_f)
- db.session.commit()
- return db_f.id, (md5hash + '/' + filename)
- def delete_file(filename):
- s3, bucket = get_s3_conn(app)
- f = Files.query.filter_by(id=filename).first_or_404()
- key = f.location
- s3.delete_object(Bucket=bucket, Key=key)
- db.session.delete(f)
- db.session.commit()
- return True
- def file_handler(path):
- f = Files.query.filter_by(location=path).first_or_404()
- chal = Challenges.query.filter_by(id=f.chal).first()
- s3, bucket = get_s3_conn(app)
- if utils.is_admin() or chal is None:
- key = f.location
- url = s3.generate_presigned_url('get_object', Params = {
- 'Bucket': bucket,
- 'Key': key, })
- return redirect(url)
- if utils.user_can_view_challenges():
- if not utils.ctftime():
- if not utils.view_after_ctf():
- abort(403)
- if chal.hidden:
- abort(403)
- key = f.location
- url = s3.generate_presigned_url('get_object', Params = {
- 'Bucket': bucket,
- 'Key': key, })
- return redirect(url)
- else:
- return redirect(url_for('auth.login'))
- utils.upload_file = upload_file
- utils.delete_file = delete_file
- app.view_functions['views.file_handler'] = file_handler
|