From 1956be0f469e5870d957a8dec2fa48100a247273 Mon Sep 17 00:00:00 2001
From: Steven Guikal
Date: Tue, 5 Oct 2021 14:00:12 -0400
Subject: [PATCH] fix(FastAPI): prefill login fields with entered data
---
aurweb/routers/auth.py | 16 ++++++++--------
templates/login.html | 9 +++++++--
test/test_auth_routes.py | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 52 insertions(+), 10 deletions(-)
diff --git a/aurweb/routers/auth.py b/aurweb/routers/auth.py
index 8f37fe27..a985281e 100644
--- a/aurweb/routers/auth.py
+++ b/aurweb/routers/auth.py
@@ -9,14 +9,14 @@ import aurweb.config
from aurweb import util
from aurweb.auth import auth_required
from aurweb.models.user import User
-from aurweb.templates import make_context, render_template
+from aurweb.templates import make_variable_context, render_template
router = APIRouter()
-def login_template(request: Request, next: str, errors: list = None):
+async def login_template(request: Request, next: str, errors: list = None):
""" Provide login-specific template context to render_template. """
- context = make_context(request, "Login", next)
+ context = await make_variable_context(request, "Login", next)
context["errors"] = errors
context["url_base"] = f"{request.url.scheme}://{request.url.netloc}"
return render_template(request, "login.html", context)
@@ -25,7 +25,7 @@ def login_template(request: Request, next: str, errors: list = None):
@router.get("/login", response_class=HTMLResponse)
@auth_required(False)
async def login_get(request: Request, next: str = "/"):
- return login_template(request, next)
+ return await login_template(request, next)
@router.post("/login", response_class=HTMLResponse)
@@ -39,8 +39,8 @@ async def login_post(request: Request,
user = session.query(User).filter(User.Username == user).first()
if not user:
- return login_template(request, next,
- errors=["Bad username or password."])
+ return await login_template(request, next,
+ errors=["Bad username or password."])
cookie_timeout = 0
@@ -50,8 +50,8 @@ async def login_post(request: Request,
sid = user.login(request, passwd, cookie_timeout)
if not sid:
- return login_template(request, next,
- errors=["Bad username or password."])
+ return await login_template(request, next,
+ errors=["Bad username or password."])
login_timeout = aurweb.config.getint("options", "login_timeout")
diff --git a/templates/login.html b/templates/login.html
index da7bd722..3c4f945f 100644
--- a/templates/login.html
+++ b/templates/login.html
@@ -45,7 +45,8 @@
+ maxlength="254" autofocus="autofocus"
+ value="{{ user or '' }}">
@@ -57,7 +58,11 @@
-
+
diff --git a/test/test_auth_routes.py b/test/test_auth_routes.py
index 1d8f9cbe..313f9927 100644
--- a/test/test_auth_routes.py
+++ b/test/test_auth_routes.py
@@ -160,6 +160,11 @@ def test_login_missing_username():
response = request.post("/login", data=post_data)
assert "AURSID" not in response.cookies
+ # Make sure password isn't prefilled and remember_me isn't checked.
+ content = response.content.decode()
+ assert post_data["passwd"] not in content
+ assert "checked" not in content
+
def test_login_remember_me():
post_data = {
@@ -188,6 +193,26 @@ def test_login_remember_me():
assert _session.LastUpdateTS < expected_ts + 5
+def test_login_incorrect_password_remember_me():
+ post_data = {
+ "user": "test",
+ "passwd": "badPassword",
+ "next": "/",
+ "remember_me": "on"
+ }
+
+ with client as request:
+ response = request.post("/login", data=post_data)
+ assert "AURSID" not in response.cookies
+
+ # Make sure username is prefilled, password isn't prefilled, and remember_me
+ # is checked.
+ content = response.content.decode()
+ assert post_data["user"] in content
+ assert post_data["passwd"] not in content
+ assert "checked" in content
+
+
def test_login_missing_password():
post_data = {
"user": "test",
@@ -198,6 +223,11 @@ def test_login_missing_password():
response = request.post("/login", data=post_data)
assert "AURSID" not in response.cookies
+ # Make sure username is prefilled and remember_me isn't checked.
+ content = response.content.decode()
+ assert post_data["user"] in content
+ assert "checked" not in content
+
def test_login_incorrect_password():
post_data = {
@@ -209,3 +239,10 @@ def test_login_incorrect_password():
with client as request:
response = request.post("/login", data=post_data)
assert "AURSID" not in response.cookies
+
+ # Make sure username is prefilled, password isn't prefilled and remember_me
+ # isn't checked.
+ content = response.content.decode()
+ assert post_data["user"] in content
+ assert post_data["passwd"] not in content
+ assert "checked" not in content