This commit is contained in:
klein panic
2024-10-01 20:14:14 -04:00
parent b3e876bd4c
commit da9156aaa3
2243 changed files with 384830 additions and 148 deletions

View File

@@ -1,77 +1,149 @@
# server/app.py
from flask import Flask, request, jsonify, render_template, redirect, url_for, send_from_directory
from flask import Flask, request, render_template, redirect, url_for, session, send_from_directory
from flask_talisman import Talisman
from functools import wraps
import os
from security import validate_user
from data_handler import save_link, save_file, retrieve_uploads, handle_download, get_file_path
app = Flask(__name__, template_folder='../templates')
Talisman(app)
app.secret_key = os.urandom(24) # Generate a more secure secret key
talisman = Talisman(app, content_security_policy={
'default-src': ["'self'"],
'script-src': ["'self'", "'unsafe-inline'"] # Allow inline scripts
})
RECEIVED_FILES_DIR = "../assets"
if not os.path.exists(RECEIVED_FILES_DIR):
os.makedirs(RECEIVED_FILES_DIR)
UPLOAD_DIRECTORY = "../assets"
if not os.path.exists(UPLOAD_DIRECTORY):
os.makedirs(UPLOAD_DIRECTORY)
# Data storage for links and images
uploaded_links = []
uploaded_images = []
# Login required decorator
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'username' not in session:
print("User is not logged in, redirecting to login page")
return redirect(url_for('login', next=request.url))
print("User is logged in, proceeding to requested page")
return f(*args, **kwargs)
return decorated_function
@app.before_request
def ensure_login():
if 'username' not in session and request.endpoint not in ('login', 'static'):
return redirect(url_for('login'))
@app.route('/')
@login_required
def index():
return render_template("index.html")
@app.route('/upload/link', methods=['POST'])
def upload_link():
data = request.form
if 'link' not in data or 'uploader' not in data:
return jsonify({"error": "Link and uploader's name are required"}), 400
link_info = {'link': data['link'], 'uploader': data['uploader']}
uploaded_links.append(link_info)
with open(os.path.join(RECEIVED_FILES_DIR, "links.txt"), "a") as f:
f.write(f"{data['uploader']}: {data['link']}\n")
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
valid, message = validate_user(username, password)
if valid:
session['username'] = username
return redirect(url_for('index'))
else:
return render_template("login.html", error=message)
return render_template("login.html")
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for('login'))
@app.route('/upload/link', methods=['POST'])
@login_required
def upload_link():
link = request.form['link']
uploader = session['username']
save_link(uploader, link)
return redirect(url_for('index'))
@app.route('/upload/image', methods=['POST'])
def upload_image():
if 'file' not in request.files or 'uploader' not in request.form:
return jsonify({"error": "File and uploader's name are required"}), 400
@app.route('/upload/file', methods=['POST'])
@login_required
def upload_file():
if 'file' not in request.files:
return redirect(url_for('index'))
file = request.files['file']
uploader = request.form['uploader']
if file.filename == '':
return jsonify({"error": "No selected file"}), 400
save_path = os.path.join(RECEIVED_FILES_DIR, file.filename)
file.save(save_path)
uploaded_images.append({'filename': file.filename, 'uploader': uploader})
uploader = session['username']
save_file(uploader, file)
return redirect(url_for('index'))
@app.route('/uploads')
@login_required
def view_uploads():
return render_template("uploads.html", links=uploaded_links, images=uploaded_images)
uploads = retrieve_uploads()
# Categorizing uploads
links = [upload for upload in uploads if upload[2] == 'link']
videos = [upload for upload in uploads if upload[2] == 'file' and upload[3].lower().endswith(('.mp4', '.mkv', '.avi'))]
photos = [upload for upload in uploads if upload[2] == 'file' and upload[3].lower().endswith(('.jpg', '.jpeg', '.png', '.gif'))]
misc = [upload for upload in uploads if upload[2] == 'file' and upload not in videos + photos]
@app.route('/assets/<filename>')
def get_image(filename):
return send_from_directory(RECEIVED_FILES_DIR, filename)
return render_template(
"uploads.html",
links=links,
videos=videos,
photos=photos,
misc=misc,
username=session['username']
)
@app.route('/rename/<filename>', methods=['POST'])
def rename_file(filename):
new_name = request.form.get('new_name')
if new_name and os.path.exists(os.path.join(RECEIVED_FILES_DIR, filename)):
os.rename(os.path.join(RECEIVED_FILES_DIR, filename), os.path.join(RECEIVED_FILES_DIR, new_name))
# Update internal records
for image in uploaded_images:
if image['filename'] == filename:
image['filename'] = new_name
break
@app.route('/download_link/<int:link_id>', methods=['GET'])
@login_required
def download_link(link_id):
uploader = session['username']
upload = handle_download(link_id, uploader)
if upload[2] == 'link':
link_content = upload[3]
# Create a unique filename
x = 1
while os.path.exists(f"link_{x}.txt"):
x += 1
filename = f"link_{x}.txt"
# Save the link content to the file
with open(filename, 'w') as f:
f.write(link_content)
# Serve the file
return send_from_directory(directory=os.getcwd(), filename=filename, as_attachment=True)
@app.route('/download_all_links', methods=['GET'])
@login_required
def download_all_links():
links = [upload for upload in retrieve_uploads() if upload[2] == 'link']
if len(links) > 1:
with open("links_data.txt", 'w') as f:
for link in links:
f.write(link[3] + "\n")
return send_from_directory(directory=os.getcwd(), filename="links_data.txt", as_attachment=True)
else:
return redirect(url_for('view_uploads'))
return jsonify({"error": "Invalid file name"}), 400
@app.route('/download/<int:upload_id>', methods=['GET'])
@login_required
def download(upload_id):
uploader = session['username']
upload = handle_download(upload_id, uploader)
if upload[2] == 'link':
return f"<a href='{upload[3]}' target='_blank'>{upload[3]}</a>"
elif upload[2] == 'file':
# Integrate get_file_path here
file_path = get_file_path(upload[3])
return send_from_directory(os.path.dirname(file_path), os.path.basename(file_path), as_attachment=True)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, ssl_context='adhoc')