Implement basic authentication

Initial working implementation, would require more polishing, but at
least it works for now.
This commit is contained in:
Dendy 2024-02-14 13:30:57 +01:00
parent b4d5146fdc
commit cf694a0d61
4 changed files with 74 additions and 1 deletions

View File

@ -1,6 +1,8 @@
name = "Folder share" name = "Folder share"
base_path = "/path/to/folder" base_path = "/path/to/folder"
favicon = "/.favicon.png" favicon = "/.favicon.png"
password = "publicpass"
admin_password = "verysecurepass"
[qbittorrent] [qbittorrent]
base_url = "http://127.0.0.1:8080" base_url = "http://127.0.0.1:8080"

View File

@ -2,10 +2,11 @@
import os 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 file
from . import config from . import config
from . import auth
app = Flask( app = Flask(
__name__, __name__,
@ -21,6 +22,7 @@ app.jinja_env.globals.update(
@app.route('/', defaults={'path': ''}) @app.route('/', defaults={'path': ''})
@app.route('/<path:path>') @app.route('/<path:path>')
@auth.requires_auth
def index(path): def index(path):
internal_path = os.path.join(config.get('base_path'), path) internal_path = os.path.join(config.get('base_path'), path)
path = '/' + path path = '/' + path
@ -62,6 +64,7 @@ def index(path):
@app.route('/search') @app.route('/search')
@auth.requires_auth
def search(): def search():
q = request.args.get('q', '') q = request.args.get('q', '')
@ -85,3 +88,27 @@ def search():
), ),
200, 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',
}
)

31
src/auth.py Normal file
View File

@ -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

13
templates/auth.html Normal file
View File

@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block title %}Secret required{% endblock %}
{% block body %}
<h1>Secret required</h1>
<form method="POST" action="/auth">
<input type="hidden" name="location" value="{{ path }}">
<input type="text" name="pass" />
<input type="submit" />
</form>
<p style="color:red;">{{ error_msg|default('') }}</p>
{% endblock %}