Lol
This commit is contained in:
BIN
server/__pycache__/data_handler.cpython-311.pyc
Normal file
BIN
server/__pycache__/data_handler.cpython-311.pyc
Normal file
Binary file not shown.
BIN
server/__pycache__/db_setup.cpython-311.pyc
Normal file
BIN
server/__pycache__/db_setup.cpython-311.pyc
Normal file
Binary file not shown.
Binary file not shown.
209
server/app.py
209
server/app.py
@@ -1,25 +1,44 @@
|
||||
# server/app.py
|
||||
from flask import Flask, request, jsonify, render_template, redirect, url_for, session
|
||||
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, identify_uploader
|
||||
from security import validate_user
|
||||
from data_handler import save_link, save_file, retrieve_uploads, handle_download, get_file_path
|
||||
from datetime import datetime
|
||||
|
||||
app = Flask(__name__, template_folder='../templates')
|
||||
app.secret_key = 'super_secret_key' # Change this to a more secure key for production
|
||||
Talisman(app)
|
||||
app.secret_key = os.urandom(24)
|
||||
talisman = Talisman(app, content_security_policy={
|
||||
'default-src': ["'self'"],
|
||||
'script-src': ["'self'", "'unsafe-inline'"]
|
||||
})
|
||||
|
||||
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 = []
|
||||
DOWNLOADS_DIRECTORY = os.path.expanduser("~/Downloads")
|
||||
if not os.path.exists(DOWNLOADS_DIRECTORY):
|
||||
os.makedirs(DOWNLOADS_DIRECTORY)
|
||||
|
||||
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():
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
return render_template("index.html")
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
@@ -27,83 +46,143 @@ def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
password = request.form['password']
|
||||
if validate_user(username, password):
|
||||
valid, message = validate_user(username, password)
|
||||
|
||||
if valid:
|
||||
session['username'] = username
|
||||
return redirect(url_for('index'))
|
||||
else:
|
||||
return "Invalid credentials. Please try again.", 403
|
||||
return render_template("login.html", error=message)
|
||||
|
||||
return render_template("login.html")
|
||||
|
||||
@app.route('/logout')
|
||||
def logout():
|
||||
session.pop('username', None)
|
||||
session.clear()
|
||||
return redirect(url_for('login'))
|
||||
|
||||
@app.route('/upload/link', methods=['POST'])
|
||||
@login_required
|
||||
def upload_link():
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
|
||||
data = request.form
|
||||
if 'link' not in data:
|
||||
return jsonify({"error": "No link provided"}), 400
|
||||
|
||||
uploader = identify_uploader()
|
||||
link_info = {'link': data['link'], 'uploader': uploader}
|
||||
uploaded_links.append(link_info)
|
||||
|
||||
with open(os.path.join(RECEIVED_FILES_DIR, "links.txt"), "a") as f:
|
||||
f.write(f"{uploader}: {data['link']}\n")
|
||||
|
||||
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 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
|
||||
@app.route('/upload/file', methods=['POST'])
|
||||
@login_required
|
||||
def upload_file():
|
||||
if 'file' not in request.files:
|
||||
return jsonify({"error": "No file provided"}), 400
|
||||
|
||||
return redirect(url_for('index'))
|
||||
|
||||
file = request.files['file']
|
||||
if file.filename == '':
|
||||
return jsonify({"error": "No selected file"}), 400
|
||||
|
||||
uploader = identify_uploader()
|
||||
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():
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
uploads = retrieve_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]
|
||||
|
||||
return render_template("uploads.html", links=uploaded_links, images=uploaded_images)
|
||||
return render_template(
|
||||
"uploads.html",
|
||||
links=links,
|
||||
videos=videos,
|
||||
photos=photos,
|
||||
misc=misc,
|
||||
username=session['username']
|
||||
)
|
||||
|
||||
@app.route('/assets/<filename>')
|
||||
def get_image(filename):
|
||||
return send_from_directory(RECEIVED_FILES_DIR, filename)
|
||||
@app.route('/download_link/<int:link_id>', methods=['GET'])
|
||||
@login_required
|
||||
def download_link(link_id):
|
||||
upload = handle_download(link_id)
|
||||
|
||||
@app.route('/rename/<filename>', methods=['POST'])
|
||||
def rename_file(filename):
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
if upload[2] == 'link':
|
||||
link_content = upload[3]
|
||||
|
||||
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))
|
||||
x = 1
|
||||
while os.path.exists(os.path.join(DOWNLOADS_DIRECTORY, f"link_{x}.txt")):
|
||||
x += 1
|
||||
filename = f"link_{x}.txt"
|
||||
|
||||
filepath = os.path.join(DOWNLOADS_DIRECTORY, filename)
|
||||
with open(filepath, 'w') as f:
|
||||
f.write(link_content)
|
||||
|
||||
response = send_from_directory(DOWNLOADS_DIRECTORY, filename, as_attachment=True)
|
||||
|
||||
handle_download(link_id, delete_only=True)
|
||||
|
||||
return response
|
||||
return "Link Not found", 404
|
||||
|
||||
@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:
|
||||
current_date = datetime.now().strftime("%m-%d-%Y")
|
||||
filename = f"links_{current_date}.txt"
|
||||
|
||||
for image in uploaded_images:
|
||||
if image['filename'] == filename:
|
||||
image['filename'] = new_name
|
||||
break
|
||||
|
||||
links_file_path = os.path.join(DOWNLOADS_DIRECTORY, filename)
|
||||
with open(links_file_path, 'w') as f:
|
||||
for link in links:
|
||||
f.write(link[3] + "\n")
|
||||
|
||||
# Serve the combined links file from the Downloads directory
|
||||
response = send_from_directory(DOWNLOADS_DIRECTORY, filename, as_attachment=True)
|
||||
|
||||
# Now delete all the link entries from the database after serving
|
||||
for link in links:
|
||||
handle_download(link[0], delete_only=True)
|
||||
|
||||
return response
|
||||
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):
|
||||
upload = handle_download(upload_id)
|
||||
|
||||
if not upload:
|
||||
print(f"Error: No upload found with ID {upload_id}")
|
||||
return "The requested file does not exist or you do not have permission to access it.", 404
|
||||
|
||||
if upload[2] == 'file':
|
||||
file_path = get_file_path(upload[3])
|
||||
print(f"Trying to download file: {file_path}")
|
||||
|
||||
if not os.path.isfile(file_path):
|
||||
print(f"Error: File not found at {file_path}")
|
||||
return "File not found", 404
|
||||
|
||||
response = send_from_directory(os.path.dirname(file_path), os.path.basename(file_path), as_attachment=True)
|
||||
|
||||
handle_download(upload_id, delete_only=True)
|
||||
|
||||
return response
|
||||
|
||||
@app.route('/delete_link/<int:link_id>', methods=['GET'])
|
||||
@login_required
|
||||
def delete_link(link_id):
|
||||
handle_download(link_id, delete_only=True)
|
||||
return redirect(url_for('view_uploads'))
|
||||
|
||||
@app.route('/delete_file/<int:file_id>', methods=['GET'])
|
||||
@login_required
|
||||
def delete_file(file_id):
|
||||
handle_download(file_id, delete_only=True)
|
||||
return redirect(url_for('view_uploads'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5000, ssl_context='adhoc')
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
56
server/data_handler.py
Normal file
56
server/data_handler.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import os
|
||||
import sqlite3 # Ensure sqlite3 is imported
|
||||
from db_setup import add_upload, get_uploads, DATABASE
|
||||
|
||||
UPLOAD_DIRECTORY = "../assets" # Directory to store uploaded files
|
||||
|
||||
def save_link(uploader, link):
|
||||
add_upload(uploader, 'link', link)
|
||||
|
||||
def save_file(uploader, file):
|
||||
# Ensure upload directory exists
|
||||
if not os.path.exists(UPLOAD_DIRECTORY):
|
||||
os.makedirs(UPLOAD_DIRECTORY)
|
||||
|
||||
file_path = os.path.join(UPLOAD_DIRECTORY, file.filename)
|
||||
file.save(file_path)
|
||||
add_upload(uploader, 'file', file.filename)
|
||||
|
||||
def retrieve_uploads():
|
||||
return get_uploads()
|
||||
|
||||
def handle_download(upload_id, uploader=None, delete_only=False):
|
||||
conn = sqlite3.connect(DATABASE)
|
||||
c = conn.cursor()
|
||||
|
||||
# Fetch the upload entry by ID only (remove the uploader check)
|
||||
c.execute('SELECT * FROM uploads WHERE id = ?', (upload_id,))
|
||||
upload = c.fetchone()
|
||||
|
||||
if not upload:
|
||||
print(f"Error: No entry found in the database for ID {upload_id}")
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
if delete_only:
|
||||
# Delete the entry from the database
|
||||
c.execute('DELETE FROM uploads WHERE id = ?', (upload_id,))
|
||||
conn.commit()
|
||||
|
||||
# Additionally, remove the file from the filesystem if it is a file upload
|
||||
if upload[2] == 'file':
|
||||
file_path = get_file_path(upload[3])
|
||||
if os.path.exists(file_path):
|
||||
os.remove(file_path)
|
||||
print(f"Successfully removed file from filesystem: {file_path}")
|
||||
else:
|
||||
print(f"File not found in filesystem, could not delete: {file_path}")
|
||||
|
||||
conn.close()
|
||||
return None
|
||||
|
||||
conn.close()
|
||||
return upload
|
||||
|
||||
def get_file_path(filename):
|
||||
return os.path.abspath(os.path.join(UPLOAD_DIRECTORY, filename))
|
||||
77
server/db_setup.py
Normal file
77
server/db_setup.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# server/db_setup.py
|
||||
import sqlite3
|
||||
import hashlib
|
||||
from contextlib import closing
|
||||
|
||||
DATABASE = 'transfer_service.db'
|
||||
|
||||
def initialize_db():
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
# Create users table
|
||||
c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
login_attempts INTEGER DEFAULT 0
|
||||
)
|
||||
''')
|
||||
|
||||
# Create uploads table for storing links, files, and images
|
||||
c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS uploads (
|
||||
id INTEGER PRIMARY KEY,
|
||||
uploader TEXT NOT NULL,
|
||||
file_type TEXT NOT NULL, -- 'link', 'file', or 'image'
|
||||
content TEXT NOT NULL, -- The actual link, filename, or file path
|
||||
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''')
|
||||
|
||||
conn.commit()
|
||||
|
||||
def add_user(username, password):
|
||||
hashed_password = hashlib.sha256(password.encode()).hexdigest()
|
||||
try:
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, hashed_password))
|
||||
conn.commit()
|
||||
print(f"User '{username}' added successfully.")
|
||||
except sqlite3.IntegrityError:
|
||||
print(f"User '{username}' already exists.")
|
||||
|
||||
def get_user(username):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, closing(conn.cursor()) as c:
|
||||
c.execute('SELECT username, password, login_attempts FROM users WHERE username = ?', (username,))
|
||||
return c.fetchone()
|
||||
|
||||
def reset_login_attempts(username):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('UPDATE users SET login_attempts = 0 WHERE username = ?', (username,))
|
||||
conn.commit()
|
||||
|
||||
def increment_login_attempts(username):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('UPDATE users SET login_attempts = login_attempts + 1 WHERE username = ?', (username,))
|
||||
conn.commit()
|
||||
|
||||
def add_upload(uploader, file_type, content):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('INSERT INTO uploads (uploader, file_type, content) VALUES (?, ?, ?)', (uploader, file_type, content))
|
||||
conn.commit()
|
||||
|
||||
def get_uploads():
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, closing(conn.cursor()) as c:
|
||||
c.execute('SELECT id, uploader, file_type, content FROM uploads')
|
||||
return c.fetchall()
|
||||
|
||||
def delete_upload(upload_id):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('DELETE FROM uploads WHERE id = ?', (upload_id,))
|
||||
conn.commit()
|
||||
|
||||
if __name__ == '__main__':
|
||||
initialize_db()
|
||||
# Example of initializing users (only run manually)
|
||||
# add_user('iphone_user', 'your_secure_password')
|
||||
# add_user('laptop_user', 'your_secure_password')
|
||||
77
server/db_setup.py.bak
Normal file
77
server/db_setup.py.bak
Normal file
@@ -0,0 +1,77 @@
|
||||
# server/db_setup.py
|
||||
import sqlite3
|
||||
import hashlib
|
||||
from contextlib import closing
|
||||
|
||||
DATABASE = 'transfer_service.db'
|
||||
|
||||
def initialize_db():
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
# Create users table
|
||||
c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
login_attempts INTEGER DEFAULT 0
|
||||
)
|
||||
''')
|
||||
|
||||
# Create uploads table for storing links, files, and images
|
||||
c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS uploads (
|
||||
id INTEGER PRIMARY KEY,
|
||||
uploader TEXT NOT NULL,
|
||||
file_type TEXT NOT NULL, -- 'link', 'file', or 'image'
|
||||
content TEXT NOT NULL, -- The actual link, filename, or file path
|
||||
uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
''')
|
||||
|
||||
conn.commit()
|
||||
|
||||
def add_user(username, password):
|
||||
hashed_password = hashlib.sha256(password.encode()).hexdigest()
|
||||
try:
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, hashed_password))
|
||||
conn.commit()
|
||||
print(f"User '{username}' added successfully.")
|
||||
except sqlite3.IntegrityError:
|
||||
print(f"User '{username}' already exists.")
|
||||
|
||||
def get_user(username):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, closing(conn.cursor()) as c:
|
||||
c.execute('SELECT username, password, login_attempts FROM users WHERE username = ?', (username,))
|
||||
return c.fetchone()
|
||||
|
||||
def reset_login_attempts(username):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('UPDATE users SET login_attempts = 0 WHERE username = ?', (username,))
|
||||
conn.commit()
|
||||
|
||||
def increment_login_attempts(username):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('UPDATE users SET login_attempts = login_attempts + 1 WHERE username = ?', (username,))
|
||||
conn.commit()
|
||||
|
||||
def add_upload(uploader, file_type, content):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('INSERT INTO uploads (uploader, file_type, content) VALUES (?, ?, ?)', (uploader, file_type, content))
|
||||
conn.commit()
|
||||
|
||||
def get_uploads():
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, closing(conn.cursor()) as c:
|
||||
c.execute('SELECT id, uploader, file_type, content FROM uploads')
|
||||
return c.fetchall()
|
||||
|
||||
def delete_upload(upload_id):
|
||||
with closing(sqlite3.connect(DATABASE)) as conn, conn, closing(conn.cursor()) as c:
|
||||
c.execute('DELETE FROM uploads WHERE id = ?', (upload_id,))
|
||||
conn.commit()
|
||||
|
||||
if __name__ == '__main__':
|
||||
initialize_db()
|
||||
# Example of initializing users (only run manually)
|
||||
# add_user('iphone_user', 'your_secure_password')
|
||||
# add_user('laptop_user', 'your_secure_password')
|
||||
@@ -1,33 +1,40 @@
|
||||
# server/security.py
|
||||
from flask import request
|
||||
import platform
|
||||
from flask import request, session
|
||||
import hashlib
|
||||
from db_setup import get_user, increment_login_attempts, reset_login_attempts
|
||||
|
||||
# Mock user database (username: password) - replace with a real database
|
||||
USER_DATABASE = {
|
||||
"iphone_user": hashlib.sha256("iphone_password".encode()).hexdigest(),
|
||||
"laptop_user": hashlib.sha256("laptop_password".encode()).hexdigest(),
|
||||
}
|
||||
MAX_ATTEMPTS = 3
|
||||
|
||||
# Function to validate user credentials
|
||||
def validate_user(username, password):
|
||||
user_data = get_user(username)
|
||||
if not user_data:
|
||||
return False, "User does not exist."
|
||||
|
||||
stored_username, stored_password, login_attempts = user_data
|
||||
|
||||
if login_attempts >= MAX_ATTEMPTS:
|
||||
return False, "Maximum login attempts exceeded. Please contact the administrator."
|
||||
|
||||
hashed_password = hashlib.sha256(password.encode()).hexdigest()
|
||||
return USER_DATABASE.get(username) == hashed_password
|
||||
|
||||
if hashed_password == stored_password:
|
||||
reset_login_attempts(username)
|
||||
return True, "Login successful."
|
||||
else:
|
||||
increment_login_attempts(username)
|
||||
return False, f"Invalid credentials. {MAX_ATTEMPTS - login_attempts - 1} attempt(s) remaining."
|
||||
|
||||
# Function to extract device information
|
||||
def get_device_info():
|
||||
user_agent = request.headers.get('User-Agent', 'Unknown')
|
||||
return {
|
||||
"ip": request.remote_addr,
|
||||
"user_agent": user_agent,
|
||||
"isa": platform.machine(), # Get system architecture
|
||||
"os": platform.system(), # Get OS
|
||||
}
|
||||
|
||||
# Function to identify the uploader based on device info
|
||||
def identify_uploader():
|
||||
device_info = get_device_info()
|
||||
if "iPhone" in device_info['user_agent']:
|
||||
return f"Uploaded by iPhone (IP: {device_info['ip']})"
|
||||
else:
|
||||
return f"Uploaded by {device_info['isa']} {device_info['os']} (IP: {device_info['ip']})"
|
||||
|
||||
def get_device_info():
|
||||
user_agent = request.headers.get('User-Agent', 'Unknown')
|
||||
return {
|
||||
"ip": request.remote_addr,
|
||||
"user_agent": user_agent,
|
||||
}
|
||||
|
||||
|
||||
BIN
server/transfer_service.db
Normal file
BIN
server/transfer_service.db
Normal file
Binary file not shown.
Reference in New Issue
Block a user