From 541029a02d1854ca6d6f3b3f40f8b5782de1913c Mon Sep 17 00:00:00 2001 From: Shirkanesi Date: Sat, 19 Aug 2023 00:59:53 +0200 Subject: [PATCH 1/5] Add common names for venv to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 8f16228..9a684f2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ __pycache__ *.swp jon/config.json elm-stuff/ +venv/ +.venv/ From bc9336ef21e5636d442dff1da36d5e759ed4a088 Mon Sep 17 00:00:00 2001 From: Shirkanesi Date: Sat, 19 Aug 2023 00:43:12 +0200 Subject: [PATCH 2/5] Initial work on auth-tokens --- jon/__init__.py | 9 +++++++++ jon/auth.py | 44 +++++++++++++++++++++++++++++++++++++++++ jon/templates/base.html | 1 + 3 files changed, 54 insertions(+) create mode 100644 jon/auth.py diff --git a/jon/__init__.py b/jon/__init__.py index 7766f92..01498d4 100644 --- a/jon/__init__.py +++ b/jon/__init__.py @@ -1,9 +1,11 @@ import inspect import json +import sys from flask import Flask, render_template from . import ( + auth, db, entry, inventory, @@ -21,6 +23,10 @@ def create_app(): db.init_app(app) + @app.before_request + def before_req_fun(): + return auth.before_request() + @app.context_processor def utility_processor(): return dict(inspect.getmembers(template_utils, inspect.isfunction)) @@ -28,8 +34,11 @@ def create_app(): app.register_blueprint(location.bp) app.register_blueprint(inventory.bp) app.register_blueprint(entry.bp) + app.register_blueprint(auth.auth) @app.route("/") def index(): return render_template("index.html") + print("Jon started. Token: %s" % auth.ACCESS_TOKEN, file=sys.stderr) + return app diff --git a/jon/auth.py b/jon/auth.py new file mode 100644 index 0000000..b843f2d --- /dev/null +++ b/jon/auth.py @@ -0,0 +1,44 @@ +from flask import Blueprint, request, redirect, make_response +from . import db +import random +import string + +auth = Blueprint('auth', __name__) + +ACCESS_TOKEN = ''.join(random.choice(string.ascii_lowercase) for i in range(64)) + +ERROR_TEXT = """ + For security-reasons we must make sure you are the person who executed jon :D
+
+ + + +
+
+ + """ + + +def before_request(): + token = request.cookies.get('token') + if token == ACCESS_TOKEN: + pass + else: + token = request.args.get('token') + next: str = request.args.get('next') or "/" + if token is None: + # TODO: make template + return ERROR_TEXT.format(next=next) + "No token provided!" + if token != ACCESS_TOKEN: + return ERROR_TEXT.format(next=next) + "Invalid token!" + else: + resp = make_response(redirect(next)) + resp.set_cookie('token', token) + return resp + + +@auth.route('/logout') +def logout(): + resp = make_response(redirect("/")) + resp.set_cookie('token', "") + return resp diff --git a/jon/templates/base.html b/jon/templates/base.html index f71f7e1..4398641 100644 --- a/jon/templates/base.html +++ b/jon/templates/base.html @@ -88,6 +88,7 @@ {% endif %} +
  • Logout
  • From c453e923ae0eb33aac18ec27a91d5ed7eab904ad Mon Sep 17 00:00:00 2001 From: Paul Brinkmeier Date: Sun, 20 Aug 2023 11:29:20 +0200 Subject: [PATCH 3/5] Use session to store authentication info instead of cookie --- jon/__init__.py | 3 ++- jon/auth.py | 42 ++++++++++++++----------------- jon/templates/base.html | 10 ++++---- jon/templates/location/index.html | 2 +- 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/jon/__init__.py b/jon/__init__.py index 01498d4..44ed8af 100644 --- a/jon/__init__.py +++ b/jon/__init__.py @@ -34,7 +34,8 @@ def create_app(): app.register_blueprint(location.bp) app.register_blueprint(inventory.bp) app.register_blueprint(entry.bp) - app.register_blueprint(auth.auth) + app.register_blueprint(auth.bp) + @app.route("/") def index(): return render_template("index.html") diff --git a/jon/auth.py b/jon/auth.py index b843f2d..be92f46 100644 --- a/jon/auth.py +++ b/jon/auth.py @@ -1,17 +1,18 @@ -from flask import Blueprint, request, redirect, make_response -from . import db import random import string -auth = Blueprint('auth', __name__) +from flask import Blueprint, make_response, request, redirect, session + +bp = Blueprint('auth', __name__, url_prefix="/auth") + ACCESS_TOKEN = ''.join(random.choice(string.ascii_lowercase) for i in range(64)) + ERROR_TEXT = """ For security-reasons we must make sure you are the person who executed jon :D
    -

    @@ -20,25 +21,20 @@ ERROR_TEXT = """ def before_request(): - token = request.cookies.get('token') - if token == ACCESS_TOKEN: - pass - else: - token = request.args.get('token') - next: str = request.args.get('next') or "/" - if token is None: - # TODO: make template - return ERROR_TEXT.format(next=next) + "No token provided!" - if token != ACCESS_TOKEN: - return ERROR_TEXT.format(next=next) + "Invalid token!" - else: - resp = make_response(redirect(next)) - resp.set_cookie('token', token) - return resp + """ + If the correct token query parameter is passed along with any request, + we mark this session authenticated by setting `session["authenticated"]`. + """ + if "token" in request.args: + if request.args["token"] == ACCESS_TOKEN: + session["authenticated"] = () + return redirect(request.path) + + if not "authenticated" in session: + return ERROR_TEXT, 403 -@auth.route('/logout') +@bp.get("/logout") def logout(): - resp = make_response(redirect("/")) - resp.set_cookie('token', "") - return resp + session.pop("authenticated", None) + return redirect("/") diff --git a/jon/templates/base.html b/jon/templates/base.html index 4398641..07b30b8 100644 --- a/jon/templates/base.html +++ b/jon/templates/base.html @@ -76,10 +76,10 @@

    jon

    diff --git a/jon/templates/location/index.html b/jon/templates/location/index.html index c66f8d2..c395213 100644 --- a/jon/templates/location/index.html +++ b/jon/templates/location/index.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block content %} -
    + - -
    -
    - - """ +ALLOWED_PATHS = [ + "/favicon.ico", + "/static/jon.css" +] def before_request(): """ If the correct token query parameter is passed along with any request, we mark this session authenticated by setting `session["authenticated"]`. - Unless the session is authenticated, all requests results in a 403 FORBIDDEN. + Unless the session is authenticated, all requests result in a 403 FORBIDDEN. """ if "token" in request.args: if request.args["token"] == ACCESS_TOKEN: @@ -32,8 +27,12 @@ def before_request(): # Reload the page without query parameters return redirect(request.path) + # Don't deny any paths in `ALLOWED_PATHS` + if request.path in ALLOWED_PATHS: + return + if not "authenticated" in session: - return ERROR_TEXT, 403 + return render_template("auth/denied.html"), 403 @bp.get("/logout") diff --git a/jon/static/jon.css b/jon/static/jon.css new file mode 100644 index 0000000..9897996 --- /dev/null +++ b/jon/static/jon.css @@ -0,0 +1,65 @@ +html { + font-family: Helvetica, sans-serif; +} +h1 { + margin: 0; +} +nav > ul { + padding-left: 0; +} +nav > ul > li { + display: inline-block; + list-style: none; +} +nav > ul > li + li:before { + content: ' · '; +} +.current-page > a { + position: relative; +} +.current-page > a:after { + content: '↓'; + font-size: 0.8em; + box-sizing: border-box; + position: absolute; + display: block; + right: 50%; + top: -1em; + width: 1em; + text-align: center; + margin-right: -0.5em; + animation: wiggle 0.8s ease-in-out 0s infinite; + /* animation-direction: alternate; */ +} +.--align-left { + text-align: left; +} +.--align-right { + text-align: right; +} +.--centered { + text-align: center; +} +@keyframes wiggle { + 0%, 100% { margin-top: 0; } + 50% { margin-top: -0.5em; } + /* 100% { transform: rotate(1turn); } */ +} +table { + border-spacing: .5em 0; +} +th { + font-size: .8em; +} +@media print { + body { + font-size: 8px; + } +} +.form-input > label { + font-size: .8em; +} +.form-input > input:not([type=radio]), +.form-input > select { + display: block; +} diff --git a/jon/templates/auth/denied.html b/jon/templates/auth/denied.html new file mode 100644 index 0000000..1122b1b --- /dev/null +++ b/jon/templates/auth/denied.html @@ -0,0 +1,36 @@ + + + + + + jon · not authenticated + + + +
    +

    jon

    + + {% if config.DEBUG %} +
    + config +
    {% for key, value in config.items() %}{{ key }} = {{ value }}
    +{% endfor %}
    +
    + {% endif %} +
    + +
    +

    + Damit kein Schabernack getrieben wird müssen wir sicherstellen, dass du die Person bist die jon ausgeführt hat. + Gib unten das Token ein, welches jon beim Starten ausgegeben hat. +

    +
    +
    + + +
    + +
    +
    + + diff --git a/jon/templates/base.html b/jon/templates/base.html index 07b30b8..c4af7be 100644 --- a/jon/templates/base.html +++ b/jon/templates/base.html @@ -3,73 +3,7 @@ jon - +