fix(FastAPI): prefill login fields with entered data

This commit is contained in:
Steven Guikal 2021-10-05 14:00:12 -04:00
parent 82a3349649
commit 1956be0f46
3 changed files with 52 additions and 10 deletions

View file

@ -9,14 +9,14 @@ import aurweb.config
from aurweb import util from aurweb import util
from aurweb.auth import auth_required from aurweb.auth import auth_required
from aurweb.models.user import User 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() 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. """ """ 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["errors"] = errors
context["url_base"] = f"{request.url.scheme}://{request.url.netloc}" context["url_base"] = f"{request.url.scheme}://{request.url.netloc}"
return render_template(request, "login.html", context) 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) @router.get("/login", response_class=HTMLResponse)
@auth_required(False) @auth_required(False)
async def login_get(request: Request, next: str = "/"): 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) @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() user = session.query(User).filter(User.Username == user).first()
if not user: if not user:
return login_template(request, next, return await login_template(request, next,
errors=["Bad username or password."]) errors=["Bad username or password."])
cookie_timeout = 0 cookie_timeout = 0
@ -50,8 +50,8 @@ async def login_post(request: Request,
sid = user.login(request, passwd, cookie_timeout) sid = user.login(request, passwd, cookie_timeout)
if not sid: if not sid:
return login_template(request, next, return await login_template(request, next,
errors=["Bad username or password."]) errors=["Bad username or password."])
login_timeout = aurweb.config.getint("options", "login_timeout") login_timeout = aurweb.config.getint("options", "login_timeout")

View file

@ -45,7 +45,8 @@
</label> </label>
<input id="id_username" type="text" name="user" size="30" <input id="id_username" type="text" name="user" size="30"
maxlength="254" autofocus="autofocus"> maxlength="254" autofocus="autofocus"
value="{{ user or '' }}">
</p> </p>
<p> <p>
@ -57,7 +58,11 @@
</p> </p>
<p> <p>
<input id="id_remember_me" type="checkbox" name="remember_me"> <input id="id_remember_me" type="checkbox" name="remember_me"
{% if remember_me %}
checked="checked"
{% endif %}
>
<label for="id_remember_me"> <label for="id_remember_me">
{% trans %}Remember me{% endtrans %} {% trans %}Remember me{% endtrans %}
</label> </label>

View file

@ -160,6 +160,11 @@ def test_login_missing_username():
response = request.post("/login", data=post_data) response = request.post("/login", data=post_data)
assert "AURSID" not in response.cookies 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(): def test_login_remember_me():
post_data = { post_data = {
@ -188,6 +193,26 @@ def test_login_remember_me():
assert _session.LastUpdateTS < expected_ts + 5 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(): def test_login_missing_password():
post_data = { post_data = {
"user": "test", "user": "test",
@ -198,6 +223,11 @@ def test_login_missing_password():
response = request.post("/login", data=post_data) response = request.post("/login", data=post_data)
assert "AURSID" not in response.cookies 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(): def test_login_incorrect_password():
post_data = { post_data = {
@ -209,3 +239,10 @@ def test_login_incorrect_password():
with client as request: with client as request:
response = request.post("/login", data=post_data) response = request.post("/login", data=post_data)
assert "AURSID" not in response.cookies 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