From 35038fca8911149cacc513ef729f2a526aef7a81 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Thu, 19 Oct 2023 19:55:59 +0300 Subject: [PATCH] Login error handling and flash messages. Remove host prefix on cookies because of https://bugs.chromium.org/p/chromium/issues/detail?id=1245434 --- cista/auth.py | 40 ++++++++++++++++++++++++++++------------ cista/serve.py | 2 +- cista/session.py | 6 +++--- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/cista/auth.py b/cista/auth.py index 21b5537..32faca8 100755 --- a/cista/auth.py +++ b/cista/auth.py @@ -6,7 +6,7 @@ from unicodedata import normalize import argon2 import msgspec from html5tagger import Document -from sanic import Blueprint, html, json, redirect +from sanic import BadRequest, Blueprint, html, json, redirect from . import config, session @@ -74,6 +74,7 @@ async def login_page(request): doc.input(type="submit", value=f"Logout {name}") flash = request.cookies.flash if flash: + print("flash", flash) doc.p(flash) res = html(doc) if flash: @@ -85,15 +86,30 @@ async def login_page(request): @authbp.post("/login") async def login_post(request): json_format = request.headers.content_type == "application/json" - if json_format: - username = request.json["username"] - password = request.json["password"] - else: - username = request.form["username"][0] - password = request.form["password"][0] - if not username or not password: - raise ValueError("Missing username or password") - user = login(username, password) + try: + if json_format: + username = request.json["username"] + password = request.json["password"] + else: + username = request.form["username"][0] + password = request.form["password"][0] + if not username or not password: + raise KeyError + except KeyError: + raise BadRequest("Missing username or password") + try: + user = login(username, password) + except ValueError as e: + if json_format: + res = json({ + "status": "error", + "error": str(e), + }) + else: + res = redirect("/login") + res.cookies.add_cookie("flash", str(e), max_age=5) + print("Login error:", res.cookies) + return res if json_format: res = json({ @@ -103,7 +119,7 @@ async def login_post(request): }) else: res = redirect("/") - res.cookies.add_cookie("flash", "Logged in", host_prefix=True, max_age=5) + res.cookies.add_cookie("flash", "Logged in", max_age=5) session.create(res, username) return res @@ -111,5 +127,5 @@ async def login_post(request): async def logout_post(request): res = redirect("/") session.delete(res) - res.cookies.add_cookie("flash", "Logged out", host_prefix=True, max_age=5) + res.cookies.add_cookie("flash", "Logged out", max_age=5) return res diff --git a/cista/serve.py b/cista/serve.py index 9e0ceaa..42fae78 100755 --- a/cista/serve.py +++ b/cista/serve.py @@ -19,7 +19,7 @@ def run(dev=False): httpredir.app.prepare(port=80, motd=False) domain = opts["host"] opts["ssl"] = str(config.conffile.parent / domain) - app.prepare(**opts, motd=False, dev=dev, auto_reload=dev) + app.prepare(**opts, motd=False, dev=dev, auto_reload=dev, access_log=True) Sanic.serve() def parse_listen(listen): diff --git a/cista/session.py b/cista/session.py index a6000fc..a310f0e 100755 --- a/cista/session.py +++ b/cista/session.py @@ -21,12 +21,12 @@ def create(res, username, **kwargs): **kwargs, } s = jwt.encode(data, session_secret()) - res.cookies.add_cookie("s", s, host_prefix=True, httponly=True, max_age=max_age) + res.cookies.add_cookie("s", s, httponly=True, max_age=max_age) def update(res, s, **kwargs): s.update(kwargs) s = jwt.encode(s, session_secret()) - res.cookies.add_cookie("s", s, host_prefix=True, httponly=True, max_age=max(1, s["exp"] - int(time()))) + res.cookies.add_cookie("s", s, httponly=True, max_age=max(1, s["exp"] - int(time()))) def delete(res): - res.cookies.delete_cookie("s", host_prefix=True) + res.cookies.delete_cookie("s")