mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
This function adds f"SameSite={value}" to each cookie's header stored in response. This is needed because starlette does not currently support the `samesite` argument in Response.set_cookie. It is merged, however, and waiting for next release. Signed-off-by: Kevin Morris <kevr@0cost.org>
97 lines
3.2 KiB
Python
97 lines
3.2 KiB
Python
import copy
|
|
import os
|
|
import zoneinfo
|
|
|
|
from datetime import datetime
|
|
from http import HTTPStatus
|
|
from urllib.parse import quote_plus
|
|
|
|
import jinja2
|
|
|
|
from fastapi import Request
|
|
from fastapi.responses import HTMLResponse
|
|
|
|
import aurweb.config
|
|
|
|
from aurweb import captcha, l10n, time, util
|
|
|
|
# Prepare jinja2 objects.
|
|
loader = jinja2.FileSystemLoader(os.path.join(
|
|
aurweb.config.get("options", "aurwebdir"), "templates"))
|
|
env = jinja2.Environment(loader=loader, autoescape=True,
|
|
extensions=["jinja2.ext.i18n"])
|
|
|
|
# Add tr translation filter.
|
|
env.filters["tr"] = l10n.tr
|
|
|
|
# Utility filters.
|
|
env.filters["dt"] = util.timestamp_to_datetime
|
|
env.filters["as_timezone"] = util.as_timezone
|
|
env.filters["dedupe_qs"] = util.dedupe_qs
|
|
env.filters["urlencode"] = quote_plus
|
|
|
|
# Add captcha filters.
|
|
env.filters["captcha_salt"] = captcha.captcha_salt_filter
|
|
env.filters["captcha_cmdline"] = captcha.captcha_cmdline_filter
|
|
|
|
# Add account utility filters.
|
|
env.filters["account_url"] = util.account_url
|
|
|
|
|
|
def make_context(request: Request, title: str, next: str = None):
|
|
""" Create a context for a jinja2 TemplateResponse. """
|
|
|
|
timezone = time.get_request_timezone(request)
|
|
return {
|
|
"request": request,
|
|
"language": l10n.get_request_language(request),
|
|
"languages": l10n.SUPPORTED_LANGUAGES,
|
|
"timezone": timezone,
|
|
"timezones": time.SUPPORTED_TIMEZONES,
|
|
"title": title,
|
|
"now": datetime.now(tz=zoneinfo.ZoneInfo(timezone)),
|
|
"config": aurweb.config,
|
|
"next": next if next else request.url.path
|
|
}
|
|
|
|
|
|
async def make_variable_context(request: Request, title: str, next: str = None):
|
|
""" Make a context with variables provided by the user
|
|
(query params via GET or form data via POST). """
|
|
context = make_context(request, title, next)
|
|
to_copy = dict(request.query_params) \
|
|
if request.method.lower() == "get" \
|
|
else dict(await request.form())
|
|
|
|
for k, v in to_copy.items():
|
|
context[k] = v
|
|
|
|
return context
|
|
|
|
|
|
def render_template(request: Request,
|
|
path: str,
|
|
context: dict,
|
|
status_code: HTTPStatus = HTTPStatus.OK):
|
|
""" Render a Jinja2 multi-lingual template with some context. """
|
|
|
|
# Create a deep copy of our jinja2 environment. The environment in
|
|
# total by itself is 48 bytes large (according to sys.getsizeof).
|
|
# This is done so we can install gettext translations on the template
|
|
# environment being rendered without installing them into a global
|
|
# which is reused in this function.
|
|
templates = copy.copy(env)
|
|
|
|
translator = l10n.get_raw_translator_for_request(context.get("request"))
|
|
templates.install_gettext_translations(translator)
|
|
|
|
template = templates.get_template(path)
|
|
rendered = template.render(context)
|
|
|
|
response = HTMLResponse(rendered, status_code=status_code)
|
|
secure_cookies = aurweb.config.getboolean("options", "disable_http_login")
|
|
response.set_cookie("AURLANG", context.get("language"),
|
|
secure=secure_cookies, httponly=True)
|
|
response.set_cookie("AURTZ", context.get("timezone"),
|
|
secure=secure_cookies, httponly=True)
|
|
return util.add_samesite_fields(response, "strict")
|