hidden files, allow ips
This commit is contained in:
85
code/app.py
85
code/app.py
@@ -1,44 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from flask import (
|
||||
Flask,
|
||||
render_template,
|
||||
jsonify,
|
||||
request,
|
||||
url_for,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
send_from_directory,
|
||||
session,
|
||||
url_for,
|
||||
)
|
||||
from werkzeug.utils import secure_filename
|
||||
from revprox import ReverseProxied
|
||||
from utils.misc import random_token, hash_password, verify_password, file_date_human
|
||||
from utils.files import (
|
||||
db_add_download,
|
||||
db_delete_file,
|
||||
db_get_file,
|
||||
db_maintenance,
|
||||
db_store_file,
|
||||
file_details,
|
||||
file_list,
|
||||
file_list_simple,
|
||||
file_full_path,
|
||||
file_full_url,
|
||||
db_add_download,
|
||||
db_get_file,
|
||||
db_delete_file,
|
||||
db_maintenance,
|
||||
validate_upload_token,
|
||||
file_list,
|
||||
file_list_simple,
|
||||
invalidate_upload_token,
|
||||
new_upload_token,
|
||||
validate_upload_token,
|
||||
)
|
||||
import logging
|
||||
from utils.misc import (
|
||||
file_date_human,
|
||||
hash_password,
|
||||
is_ip_allowed,
|
||||
random_token,
|
||||
verify_password,
|
||||
)
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format=f"[%(asctime)s] [%(levelname)s] %(message)s",
|
||||
)
|
||||
|
||||
__VERSION__ = "20230828.0"
|
||||
__VERSION__ = "20240114.0"
|
||||
app = Flask(__name__)
|
||||
app.config.from_object(__name__)
|
||||
app.config.from_prefixed_env()
|
||||
@@ -81,6 +88,8 @@ def upload():
|
||||
-H "Max-Downloads: 4000" \
|
||||
-H "Expires-Days: 14" \
|
||||
-H "Password: mypass" \
|
||||
-H "Hidden: true" \
|
||||
-H "Allowed-IP: 10.0.0.1,10.0.0.2,10.1.*" \
|
||||
-H "Secret: dff789f0bbe8183d32542" \
|
||||
"$FLASK_PUBLIC_URL"/upload
|
||||
|
||||
@@ -115,15 +124,21 @@ def upload():
|
||||
max_dl = request.headers.get("Max-Downloads", app.config["DEFAULT_MAX_DL"])
|
||||
expires = int(time.time()) + int(app.config["DEFAULT_EXPIRE"])
|
||||
if "Expires-days" in request.headers:
|
||||
expires = int(time.time()) + 24 * 3600 * int(
|
||||
request.headers.get("Expires-days")
|
||||
)
|
||||
expires = int(time.time()) + 24 * 3600 * int(request.headers.get("Expires-days"))
|
||||
if "Expires-hours" in request.headers:
|
||||
expires = int(time.time()) + 3600 * int(request.headers.get("Expires-hours"))
|
||||
password = None
|
||||
if "Password" in request.headers:
|
||||
if request.headers["Password"] != "":
|
||||
password = hash_password(request.headers["Password"])
|
||||
hidden = None
|
||||
if "Hidden" in request.headers:
|
||||
hidden = request.headers["Hidden"].lower() == "true"
|
||||
allowed_ip = None
|
||||
if "Allowed-IP" in request.headers:
|
||||
allowed_ip = request.headers["Allowed-IP"].lower()
|
||||
if not set(allowed_ip) <= set("1234567890.*, "):
|
||||
return "IP list contains unknown characters"
|
||||
|
||||
while True:
|
||||
token = random_token()
|
||||
@@ -150,11 +165,9 @@ def upload():
|
||||
break
|
||||
f.write(chunk)
|
||||
|
||||
db_store_file(token, safe_filename, expires, max_dl, password)
|
||||
db_store_file(token, safe_filename, expires, max_dl, password, ips=allowed_ip, hidden=hidden)
|
||||
download_url = file_full_url(token, safe_filename)
|
||||
app.logger.info(
|
||||
f"Upload: {download_url} MaxDL:{max_dl} Exp:{file_date_human(expires)}"
|
||||
)
|
||||
app.logger.info(f"Upload: {download_url} MaxDL:{max_dl} Exp:{file_date_human(expires)}")
|
||||
if upload_token:
|
||||
invalidate_upload_token(upload_token)
|
||||
return "File uploaded\n%s\n" % (download_url,), 200
|
||||
@@ -176,9 +189,7 @@ def upload_token():
|
||||
return "Error", 401
|
||||
expires = int(time.time()) + int(app.config["DEFAULT_EXPIRE"])
|
||||
if "Expires-days" in request.headers:
|
||||
expires = int(time.time()) + 24 * 3600 * int(
|
||||
request.headers.get("Expires-days")
|
||||
)
|
||||
expires = int(time.time()) + 24 * 3600 * int(request.headers.get("Expires-days"))
|
||||
token = new_upload_token(expires)
|
||||
return token, 200
|
||||
|
||||
@@ -197,6 +208,11 @@ def details(token, name):
|
||||
if secret != app.config["ACCESS_TOKEN"]:
|
||||
return "Error", 401
|
||||
details = file_details(token, name)
|
||||
if details["allowed_ip"] is not None:
|
||||
if not is_ip_allowed(
|
||||
details["allowed_ip"], request.environ.get("HTTP_X_FORWARDED_FOR", request.remote_addr), app
|
||||
):
|
||||
return "Not Allowed", 403
|
||||
return jsonify(details), 200
|
||||
|
||||
|
||||
@@ -208,6 +224,13 @@ def delete_file(name, token):
|
||||
secret = request.headers.get("Secret", "")
|
||||
if secret != app.config["ACCESS_TOKEN"]:
|
||||
return "Error", 401
|
||||
details = file_details(token, name)
|
||||
if details["allowed_ip"] is not None:
|
||||
if not is_ip_allowed(
|
||||
details["allowed_ip"], request.environ.get("HTTP_X_FORWARDED_FOR", request.remote_addr), app
|
||||
):
|
||||
return "Not Allowed", 403
|
||||
|
||||
try:
|
||||
os.remove(os.path.join(app.config["DATAFOLDER"], token, name))
|
||||
except Exception:
|
||||
@@ -307,13 +330,17 @@ def download_file(token, name):
|
||||
return "Error", 404
|
||||
db_stat = db_get_file(token, name)
|
||||
if db_stat:
|
||||
added, expires, downloads, max_dl, password_hash = db_stat
|
||||
added, expires, downloads, max_dl, password_hash, hidden, allowed_ip = db_stat
|
||||
else:
|
||||
return "Error", 404
|
||||
if allowed_ip is not None:
|
||||
if not is_ip_allowed(allowed_ip, request.environ.get("HTTP_X_FORWARDED_FOR", request.remote_addr), app):
|
||||
return "Not Allowed", 403
|
||||
# check ip list!
|
||||
if downloads >= max_dl and max_dl > -1:
|
||||
return "Expired", 401
|
||||
return "Expired", 403
|
||||
if expires < time.time():
|
||||
return "Expired", 401
|
||||
return "Expired", 403
|
||||
if password_hash:
|
||||
if verify_password(session.get(token, ""), password_hash):
|
||||
pass
|
||||
@@ -324,9 +351,7 @@ def download_file(token, name):
|
||||
return redirect(url_for("login"))
|
||||
|
||||
db_add_download(token, name)
|
||||
return send_from_directory(
|
||||
directory=os.path.join(app.config["DATAFOLDER"], token), path=name
|
||||
)
|
||||
return send_from_directory(directory=os.path.join(app.config["DATAFOLDER"], token), path=name)
|
||||
|
||||
|
||||
def print_debug(s):
|
||||
|
||||
Reference in New Issue
Block a user