From 7c641df41ef42075bac54a20286cc45d53c90c14 Mon Sep 17 00:00:00 2001 From: spitkov Date: Mon, 9 Sep 2024 22:08:21 +0200 Subject: [PATCH] Merge branch 'main' of https://git.spitkov.hu/cgcristi/aCloud --- app.py | 210 +++++++++++++- schema.sql | 6 + templates/edit_file.html | 39 +++ templates/index.html | 458 +++++++++++++++---------------- templates/login.html | 6 + templates/register.html | 6 + templates/user_files.html | 21 ++ templates/user_files_public.html | 43 +++ uploads/asdasd/index.html | 27 ++ 9 files changed, 574 insertions(+), 242 deletions(-) create mode 100644 templates/edit_file.html create mode 100644 templates/login.html create mode 100644 templates/register.html create mode 100644 templates/user_files.html create mode 100644 templates/user_files_public.html create mode 100644 uploads/asdasd/index.html diff --git a/app.py b/app.py index efcbac6..888c667 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -from flask import Flask, request, jsonify, send_from_directory, render_template, url_for, redirect +from flask import Flask, request, jsonify, send_from_directory, render_template, url_for, redirect, send_file from werkzeug.utils import secure_filename import shortuuid import os @@ -14,8 +14,11 @@ from pygments.lexers import get_lexer_by_name, guess_lexer from pygments.formatters import HtmlFormatter from pygments.util import ClassNotFound import json +from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user +import hashlib app = Flask(__name__) +app.secret_key = 'your_secret_key_here' # Add this line UPLOAD_FOLDER = './uploads' app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER DATABASE = 'data.db' @@ -77,6 +80,39 @@ cleanup_thread = threading.Thread(target=delete_old_files) cleanup_thread.daemon = True cleanup_thread.start() +login_manager = LoginManager() +login_manager.init_app(app) +login_manager.login_view = 'login' + +class User(UserMixin): + def __init__(self, id, username, password_hash): + self.id = id + self.username = username + self.password_hash = password_hash + + @staticmethod + def hash_password(password): + salt = os.urandom(32) + key = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) + return salt + key + + @staticmethod + def verify_password(stored_password, provided_password): + salt = stored_password[:32] + stored_key = stored_password[32:] + new_key = hashlib.pbkdf2_hmac('sha256', provided_password.encode('utf-8'), salt, 100000) + return stored_key == new_key + +@login_manager.user_loader +def load_user(user_id): + db = get_db() + cursor = db.cursor() + cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,)) + user = cursor.fetchone() + if user: + return User(user[0], user[1], user[2]) + return None + @app.route('/') def index(): return render_template('index.html') @@ -338,5 +374,177 @@ def download_folder_file(vanity, file_name): return send_from_directory(folder_path, file_name, as_attachment=True) return 'Not Found', 404 +@app.route('/register', methods=['GET', 'POST']) +def register(): + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + db = get_db() + cursor = db.cursor() + cursor.execute("SELECT * FROM users WHERE username = ?", (username,)) + if cursor.fetchone(): + return "Username already exists" + hashed_password = User.hash_password(password) + cursor.execute("INSERT INTO users (username, password_hash) VALUES (?, ?)", + (username, hashed_password)) + db.commit() + return redirect(url_for('login')) + return render_template('register.html') + +@app.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + db = get_db() + cursor = db.cursor() + cursor.execute("SELECT * FROM users WHERE username = ?", (username,)) + user = cursor.fetchone() + if user and User.verify_password(user[2], password): + login_user(User(user[0], user[1], user[2])) + return redirect(url_for('user_files', username=username)) + return "Invalid username or password" + return render_template('login.html') + +@app.route('/logout') +@login_required +def logout(): + logout_user() + return redirect(url_for('index')) + +@app.route('/user/') +def user_files(username): + if current_user.is_authenticated and current_user.username == username: + user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username) + if not os.path.exists(user_folder): + os.makedirs(user_folder) + files = os.listdir(user_folder) + return render_template('user_files.html', username=username, files=files) + return "Unauthorized", 401 + +@app.route('/user//upload', methods=['POST']) +@login_required +def upload_user_file(username): + if current_user.username != username: + return "Unauthorized", 401 + if 'file' not in request.files: + return 'No file part', 400 + file = request.files['file'] + if file.filename == '': + return 'No selected file', 400 + if file: + filename = secure_filename(file.filename) + file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, filename) + file.save(file_path) + return redirect(url_for('user_files', username=username)) + +@app.route('/user//delete/', methods=['POST']) +@login_required +def delete_user_file(username, filename): + if current_user.username != username: + return "Unauthorized", 401 + file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, filename) + if os.path.exists(file_path): + os.remove(file_path) + return redirect(url_for('user_files', username=username)) + +@app.route('/user//rename', methods=['POST']) +@login_required +def rename_user_file(username): + if current_user.username != username: + return "Unauthorized", 401 + old_filename = request.form['old_filename'] + new_filename = secure_filename(request.form['new_filename']) + old_path = os.path.join(app.config['UPLOAD_FOLDER'], username, old_filename) + new_path = os.path.join(app.config['UPLOAD_FOLDER'], username, new_filename) + if os.path.exists(old_path): + os.rename(old_path, new_path) + return redirect(url_for('user_files', username=username)) + +@app.route('/') +@app.route('//') +@app.route('//') +def serve_user_page(username, filename=None): + print(f"Accessing user page: {username}, filename: {filename}") # Debug print + + # Check if the username exists in the database + db = get_db() + cursor = db.cursor() + cursor.execute("SELECT * FROM users WHERE username = ?", (username,)) + user = cursor.fetchone() + if not user: + print(f"User {username} not found") # Debug print + return "User not found", 404 + + user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username) + print(f"User folder path: {user_folder}") # Debug print + + if not os.path.exists(user_folder): + print(f"User folder does not exist for {username}") # Debug print + os.makedirs(user_folder) # Create the folder if it doesn't exist + + if filename is None or filename == '': + # Try to serve index.html + index_path = os.path.join(user_folder, 'index.html') + print(f"Checking for index.html at: {index_path}") # Debug print + if os.path.exists(index_path): + print(f"Serving index.html for {username}") # Debug print + return send_file(index_path) + else: + print(f"No index.html found, listing files for {username}") # Debug print + # If no index.html, list all files + files = os.listdir(user_folder) + print(f"Files in {username}'s folder: {files}") # Debug print + return render_template('user_files_public.html', username=username, files=files) + else: + # Serve the requested file + file_path = os.path.join(user_folder, filename) + print(f"Attempting to serve file: {file_path}") # Debug print + if os.path.exists(file_path) and os.path.isfile(file_path): + print(f"Serving file: {file_path}") # Debug print + return send_file(file_path) + else: + print(f"File not found: {file_path}") # Debug print + return "File not found", 404 + +@app.route('/debug/users') +def debug_users(): + db = get_db() + cursor = db.cursor() + cursor.execute("SELECT username FROM users") + users = cursor.fetchall() + + user_files = {} + for user in users: + username = user[0] + user_folder = os.path.join(app.config['UPLOAD_FOLDER'], username) + if os.path.exists(user_folder): + user_files[username] = os.listdir(user_folder) + else: + user_files[username] = [] + + return jsonify(user_files) + +@app.route('/user//edit/', methods=['GET', 'POST']) +@login_required +def edit_file(username, filename): + if current_user.username != username: + return "Unauthorized", 401 + + file_path = os.path.join(app.config['UPLOAD_FOLDER'], username, filename) + + if request.method == 'POST': + content = request.form['content'] + with open(file_path, 'w') as file: + file.write(content) + return redirect(url_for('user_files', username=username)) + + if os.path.exists(file_path) and os.path.isfile(file_path): + with open(file_path, 'r') as file: + content = file.read() + return render_template('edit_file.html', username=username, filename=filename, content=content) + else: + return "File not found", 404 + if __name__ == '__main__': app.run(debug=True, port=7123) diff --git a/schema.sql b/schema.sql index 8b044dc..8152bd3 100644 --- a/schema.sql +++ b/schema.sql @@ -3,4 +3,10 @@ CREATE TABLE IF NOT EXISTS content ( type TEXT NOT NULL, data TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username TEXT UNIQUE NOT NULL, + password_hash TEXT NOT NULL ); \ No newline at end of file diff --git a/templates/edit_file.html b/templates/edit_file.html new file mode 100644 index 0000000..e2bdd32 --- /dev/null +++ b/templates/edit_file.html @@ -0,0 +1,39 @@ + + + + + + Edit {{ filename }} + + + + +

Editing {{ filename }}

+
+
+ + +
+ + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 1272161..de5dfd7 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,148 +3,128 @@ - aCloud + aCloud - File Sharing Service -
+ +
- +
-
-
+
- - - - + + + +
@@ -182,155 +162,151 @@
- - - - - + + + + diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 0000000..5c73e92 --- /dev/null +++ b/templates/login.html @@ -0,0 +1,6 @@ +

Login

+
+ + + +
\ No newline at end of file diff --git a/templates/register.html b/templates/register.html new file mode 100644 index 0000000..1d563ce --- /dev/null +++ b/templates/register.html @@ -0,0 +1,6 @@ +

Register

+
+ + + +
\ No newline at end of file diff --git a/templates/user_files.html b/templates/user_files.html new file mode 100644 index 0000000..3d9612f --- /dev/null +++ b/templates/user_files.html @@ -0,0 +1,21 @@ +

{{ username }}'s Files

+
+ + +
+
    +{% for file in files %} +
  • + {{ file }} +
    + +
    +
    + + + +
    + Edit +
  • +{% endfor %} +
\ No newline at end of file diff --git a/templates/user_files_public.html b/templates/user_files_public.html new file mode 100644 index 0000000..24c16e5 --- /dev/null +++ b/templates/user_files_public.html @@ -0,0 +1,43 @@ + + + + + + {{ username }}'s Files + + + +

{{ username }}'s Files

+
    + {% for file in files %} +
  • {{ file }}
  • + {% endfor %} +
+ + \ No newline at end of file diff --git a/uploads/asdasd/index.html b/uploads/asdasd/index.html new file mode 100644 index 0000000..3943ef1 --- /dev/null +++ b/uploads/asdasd/index.html @@ -0,0 +1,27 @@ +Python IDE

Python IDE