Login error handling and flash messages. Remove host prefix on cookies because of https://bugs.chromium.org/p/chromium/issues/detail?id=1245434

This commit is contained in:
Leo Vasanko 2023-10-19 19:55:59 +03:00 committed by Leo Vasanko
parent b7f7a84f60
commit 35038fca89
3 changed files with 32 additions and 16 deletions

View File

@ -6,7 +6,7 @@ from unicodedata import normalize
import argon2 import argon2
import msgspec import msgspec
from html5tagger import Document from html5tagger import Document
from sanic import Blueprint, html, json, redirect from sanic import BadRequest, Blueprint, html, json, redirect
from . import config, session from . import config, session
@ -74,6 +74,7 @@ async def login_page(request):
doc.input(type="submit", value=f"Logout {name}") doc.input(type="submit", value=f"Logout {name}")
flash = request.cookies.flash flash = request.cookies.flash
if flash: if flash:
print("flash", flash)
doc.p(flash) doc.p(flash)
res = html(doc) res = html(doc)
if flash: if flash:
@ -85,6 +86,7 @@ async def login_page(request):
@authbp.post("/login") @authbp.post("/login")
async def login_post(request): async def login_post(request):
json_format = request.headers.content_type == "application/json" json_format = request.headers.content_type == "application/json"
try:
if json_format: if json_format:
username = request.json["username"] username = request.json["username"]
password = request.json["password"] password = request.json["password"]
@ -92,8 +94,22 @@ async def login_post(request):
username = request.form["username"][0] username = request.form["username"][0]
password = request.form["password"][0] password = request.form["password"][0]
if not username or not password: if not username or not password:
raise ValueError("Missing username or password") raise KeyError
except KeyError:
raise BadRequest("Missing username or password")
try:
user = login(username, password) 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: if json_format:
res = json({ res = json({
@ -103,7 +119,7 @@ async def login_post(request):
}) })
else: else:
res = redirect("/") 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) session.create(res, username)
return res return res
@ -111,5 +127,5 @@ async def login_post(request):
async def logout_post(request): async def logout_post(request):
res = redirect("/") res = redirect("/")
session.delete(res) 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 return res

View File

@ -19,7 +19,7 @@ def run(dev=False):
httpredir.app.prepare(port=80, motd=False) httpredir.app.prepare(port=80, motd=False)
domain = opts["host"] domain = opts["host"]
opts["ssl"] = str(config.conffile.parent / domain) 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() Sanic.serve()
def parse_listen(listen): def parse_listen(listen):

View File

@ -21,12 +21,12 @@ def create(res, username, **kwargs):
**kwargs, **kwargs,
} }
s = jwt.encode(data, session_secret()) 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): def update(res, s, **kwargs):
s.update(kwargs) s.update(kwargs)
s = jwt.encode(s, session_secret()) 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): def delete(res):
res.cookies.delete_cookie("s", host_prefix=True) res.cookies.delete_cookie("s")