diff --git a/pyproject.toml b/pyproject.toml index 61b25b5..768f33d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ pyyaml = "^6.0.2" nanoid = "^2.0.0" # grung-db = {git = "https://git.evilchi.li/evilchili/grung-db.git"} grung-db = {git = "file:///home/greg/dev/grung-db/"} +flask-session = "^0.8.0" [tool.poetry.group.dev.dependencies] pytest = "*" diff --git a/src/ttfrog/app.py b/src/ttfrog/app.py index bde176c..b337b88 100644 --- a/src/ttfrog/app.py +++ b/src/ttfrog/app.py @@ -4,9 +4,9 @@ from pathlib import Path from types import SimpleNamespace from dotenv import dotenv_values -from flask import Flask +from flask import Flask, session +from flask_session import Session from grung.db import GrungDB -from grung.exceptions import UniqueConstraintError from tinydb.storages import MemoryStorage from ttfrog import schema @@ -78,6 +78,7 @@ VIEW_URI=/ config=config_file, data_root=data_root, database=data_root / f"{self.config.NAME}.json", + sessions=data_root / "session_cache" ) def initialize(self, db: GrungDB = None, force: bool = False) -> None: @@ -99,6 +100,11 @@ VIEW_URI=/ self.web.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0 self.web.config["DEBUG"] = True + self.web.config["SESSION_TYPE"] = "filesystem" + self.web.config["SESSION_REFRESH_EACH_REQUEST"] = True + self.web.config["SESSION_FILE_DIR"] = self.path.sessions + Session(self.web) + self._initialized = True def check_state(self) -> None: diff --git a/src/ttfrog/forms.py b/src/ttfrog/forms.py index cfa0e72..9159c8f 100644 --- a/src/ttfrog/forms.py +++ b/src/ttfrog/forms.py @@ -5,6 +5,8 @@ from grung.types import BackReference, Collection, Pointer, Record from ttfrog import schema +from flask import g + READ_ONLY_FIELD_TYPES = [Collection, Pointer, BackReference] @@ -30,6 +32,7 @@ class Form: continue self.record[key] = value + self.record.author = g.user return self.record diff --git a/src/ttfrog/themes/default/base.html b/src/ttfrog/themes/default/base.html index 6da2643..ddeafef 100644 --- a/src/ttfrog/themes/default/base.html +++ b/src/ttfrog/themes/default/base.html @@ -22,6 +22,8 @@ {% block menu %}{% endblock %} + Last Edited By: {{ page.author.name }} +
{% for message in get_flashed_messages() %} diff --git a/src/ttfrog/web.py b/src/ttfrog/web.py index 42acfc4..83821a1 100644 --- a/src/ttfrog/web.py +++ b/src/ttfrog/web.py @@ -1,4 +1,4 @@ -from flask import Response, render_template, request +from flask import Response, render_template, request, redirect, url_for, session, g from tinydb import where from ttfrog import app, schema, forms @@ -81,11 +81,26 @@ def index(): return rendered(get_page(create_okay=False)) +@app.web.route("/login") +def login(): + app.web.session_interface.regenerate(session) + g.user = app.db.User.search(where("name") == "admin")[0] + session['user_id'] = g.user.doc_id + return redirect(url_for("index")) + + +@app.web.route("/logout") +def logout(): + if 'user_id' in session: + del session['user_id'] + del g.user + + @app.web.route(f"{app.config.VIEW_URI}//", methods=["GET"]) @app.web.route(f"{app.config.VIEW_URI}/", methods=["GET"], defaults={'table': 'Page'}) def view(table, path): parent = get_parent(table, relative_uri()) - return rendered(get_page(request.path, table=table, create_okay=parent.doc_id is not None)) + return rendered(get_page(request.path, table=table, create_okay=parent and parent.doc_id is not None)) @app.web.route(f"{app.config.VIEW_URI}//", methods=["POST"]) @@ -110,6 +125,14 @@ def edit(table, path): return rendered(app.add_member(parent, save_data)) +@app.web.before_request +def before_request(): + if 'user_id' in session: + g.user = app.db.User.get(doc_id=session['user_id']) + elif request.endpoint != 'login': + return redirect(url_for('login')) + + @app.web.after_request def add_header(r): r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate, public, max-age=0"