Molodetz blogrol volgens DPP-template
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
from fastapi import APIRouter, Request
|
||||
|
||||
from molodetz.database import create_session, end_session, get_int_setting, get_user_by_email, get_user_by_username
|
||||
from molodetz.dependencies import json_or_form
|
||||
from molodetz.models import LoginForm
|
||||
from molodetz.responses import action_result, json_error, respond, wants_json
|
||||
from molodetz.schemas.account import LoginPageOut
|
||||
from molodetz.seo import base_seo_context
|
||||
from molodetz.templating import templates
|
||||
from molodetz.utils.audit import record
|
||||
from molodetz.utils.auth import get_current_user, invalidate_user_cache, is_account_active, verify_password_async
|
||||
from molodetz.utils.request_meta import is_secure_request, safe_next
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
def _seo(request):
|
||||
return base_seo_context(request, "Inloggen", robots="noindex,nofollow")
|
||||
|
||||
|
||||
@router.get("/login")
|
||||
async def login_page(request: Request):
|
||||
next_url = safe_next(request.query_params.get("next"), "/admin")
|
||||
return respond(request, "auth/login.html", {"errors": [], "form": {}, "next": next_url, "seo": _seo(request)}, model=LoginPageOut)
|
||||
|
||||
|
||||
@router.post("/login")
|
||||
async def login_submit(request: Request):
|
||||
data = await json_or_form(request, LoginForm)
|
||||
user = get_user_by_username(data.username) or get_user_by_email(data.username.lower())
|
||||
valid = user is not None and is_account_active(user) and await verify_password_async(data.password, user.get("password_hash"))
|
||||
if not valid:
|
||||
record(request, "auth.login.failed", result="denied", payload={"username": data.username[:64]})
|
||||
ctx = {
|
||||
"errors": ["Onbekende combinatie van naam en wachtwoord."],
|
||||
"form": {"username": data.username},
|
||||
"next": data.next,
|
||||
"seo": _seo(request),
|
||||
}
|
||||
if wants_json(request):
|
||||
return json_error(401, "Invalid credentials")
|
||||
return templates.TemplateResponse(request, "auth/login.html", ctx, status_code=400)
|
||||
days = get_int_setting("session_remember_days", 30) if data.remember else get_int_setting("session_max_age_days", 7)
|
||||
max_age = max(1, days) * 86400
|
||||
token = create_session(user["uid"], max_age)
|
||||
record(request, "auth.login", targets=[("user", user["uid"])], user=user)
|
||||
response = action_result(request, safe_next(data.next, "/admin"))
|
||||
response.set_cookie(
|
||||
key="session",
|
||||
value=token,
|
||||
max_age=max_age,
|
||||
httponly=True,
|
||||
samesite="lax",
|
||||
secure=is_secure_request(request),
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@router.post("/logout")
|
||||
async def logout(request: Request):
|
||||
user = get_current_user(request)
|
||||
token = request.cookies.get("session")
|
||||
if token:
|
||||
end_session(token, user["uid"] if user else "guest")
|
||||
invalidate_user_cache(propagate=True)
|
||||
record(request, "auth.logout", user=user)
|
||||
response = action_result(request, "/")
|
||||
response.delete_cookie("session")
|
||||
return response
|
||||
Reference in New Issue
Block a user