diff --git a/config.toml.example b/config.toml.example index 5244fd5..a88fe54 100644 --- a/config.toml.example +++ b/config.toml.example @@ -1,6 +1,8 @@ name = "Folder share" base_path = "/path/to/folder" favicon = "/.favicon.png" +password = "publicpass" +admin_password = "verysecurepass" [qbittorrent] base_url = "http://127.0.0.1:8080" diff --git a/src/__init__.py b/src/__init__.py index f19ee53..1a7ad0d 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -2,10 +2,11 @@ import os -from flask import Flask, render_template, send_file, request +from flask import Flask, Response, render_template, send_file, request from . import file from . import config +from . import auth app = Flask( __name__, @@ -21,6 +22,7 @@ app.jinja_env.globals.update( @app.route('/', defaults={'path': ''}) @app.route('/') +@auth.requires_auth def index(path): internal_path = os.path.join(config.get('base_path'), path) path = '/' + path @@ -62,6 +64,7 @@ def index(path): @app.route('/search') +@auth.requires_auth def search(): q = request.args.get('q', '') @@ -85,3 +88,27 @@ def search(): ), 200, ) + + +@app.route('/auth', methods=['POST']) +def auth_handle(): + expected_pass = config.get('password') + + if expected_pass is None: + return "You shouldn't be here.", 405 + + if request.form.get("pass", None) != expected_pass: + return render_template( + 'auth.html', + path=request.form.get("location", "/"), + error_msg="Incorrect password", + ), 403 + + return Response( + "Redirecting...", + 303, + { + 'Location': request.form.get("location", "/"), + 'Set-Cookie': 'film_session=To be changed', + } + ) diff --git a/src/auth.py b/src/auth.py new file mode 100644 index 0000000..04a91ee --- /dev/null +++ b/src/auth.py @@ -0,0 +1,31 @@ +from functools import wraps + +from flask import request, render_template +from . import config + +# FIXME: EVERYTHING is under the auth now, even files (makes sense) +# but that means that even the favicon requires authentication. + + +def auth_page(*args, **kwargs): + # TODO: Is there a better way of doing this? + path = f"{request.path}?{request.query_string.decode('utf-8')}" + + return render_template("auth.html", path=path), 403 + + +def requires_auth(f): + @wraps(f) + def decorated(*args, **kwargs): + if config.get('password') in [False, None, ""]: + return f(*args, **kwargs) + + if request.cookies.get('film_session', None) != 'To be changed': + # Not authenticated + return auth_page() + + # User properly authenticated + print(request.cookies['film_session']) + return f(*args, **kwargs) + + return decorated diff --git a/templates/auth.html b/templates/auth.html new file mode 100644 index 0000000..8706f3d --- /dev/null +++ b/templates/auth.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} + +{% block title %}Secret required{% endblock %} + +{% block body %} +

Secret required

+
+ + + +
+

{{ error_msg|default('') }}

+{% endblock %}