mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
add util.add_samesite_fields(response, value)
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>
This commit is contained in:
parent
ec632a7091
commit
91dc3efc75
6 changed files with 23 additions and 5 deletions
|
@ -6,6 +6,7 @@ from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
|
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_context, render_template
|
||||||
|
@ -63,7 +64,7 @@ async def login_post(request: Request,
|
||||||
secure_cookies = aurweb.config.getboolean("options", "disable_http_login")
|
secure_cookies = aurweb.config.getboolean("options", "disable_http_login")
|
||||||
response.set_cookie("AURSID", sid, expires=expires_at,
|
response.set_cookie("AURSID", sid, expires=expires_at,
|
||||||
secure=secure_cookies, httponly=True)
|
secure=secure_cookies, httponly=True)
|
||||||
return response
|
return util.add_samesite_fields(response, "strict")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/logout")
|
@router.get("/logout")
|
||||||
|
|
|
@ -8,6 +8,7 @@ from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
|
||||||
|
from aurweb import util
|
||||||
from aurweb.templates import make_context, render_template
|
from aurweb.templates import make_context, render_template
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
@ -50,7 +51,7 @@ async def language(request: Request,
|
||||||
secure_cookies = aurweb.config.getboolean("options", "disable_http_login")
|
secure_cookies = aurweb.config.getboolean("options", "disable_http_login")
|
||||||
response.set_cookie("AURLANG", set_lang,
|
response.set_cookie("AURLANG", set_lang,
|
||||||
secure=secure_cookies, httponly=True)
|
secure=secure_cookies, httponly=True)
|
||||||
return response
|
return util.add_samesite_fields(response, "strict")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_class=HTMLResponse)
|
@router.get("/", response_class=HTMLResponse)
|
||||||
|
|
|
@ -14,6 +14,7 @@ from starlette.requests import Request
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
import aurweb.db
|
import aurweb.db
|
||||||
|
|
||||||
|
from aurweb import util
|
||||||
from aurweb.l10n import get_translator_for_request
|
from aurweb.l10n import get_translator_for_request
|
||||||
from aurweb.schema import Bans, Sessions, Users
|
from aurweb.schema import Bans, Sessions, Users
|
||||||
|
|
||||||
|
@ -140,7 +141,7 @@ async def authenticate(request: Request, redirect: str = None, conn=Depends(aurw
|
||||||
response.set_cookie(key="SSO_ID_TOKEN", value=token["id_token"],
|
response.set_cookie(key="SSO_ID_TOKEN", value=token["id_token"],
|
||||||
path="/sso/", httponly=True,
|
path="/sso/", httponly=True,
|
||||||
secure=secure_cookies)
|
secure=secure_cookies)
|
||||||
return response
|
return util.add_samesite_fields(response, "strict")
|
||||||
else:
|
else:
|
||||||
# We’ve got a severe integrity violation.
|
# We’ve got a severe integrity violation.
|
||||||
raise Exception("Multiple accounts found for SSO account " + sub)
|
raise Exception("Multiple accounts found for SSO account " + sub)
|
||||||
|
|
|
@ -94,4 +94,4 @@ def render_template(request: Request,
|
||||||
secure=secure_cookies, httponly=True)
|
secure=secure_cookies, httponly=True)
|
||||||
response.set_cookie("AURTZ", context.get("timezone"),
|
response.set_cookie("AURTZ", context.get("timezone"),
|
||||||
secure=secure_cookies, httponly=True)
|
secure=secure_cookies, httponly=True)
|
||||||
return response
|
return util.add_samesite_fields(response, "strict")
|
||||||
|
|
|
@ -9,6 +9,7 @@ from urllib.parse import quote_plus, urlparse
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from email_validator import EmailNotValidError, EmailUndeliverableError, validate_email
|
from email_validator import EmailNotValidError, EmailUndeliverableError, validate_email
|
||||||
|
from fastapi.responses import Response
|
||||||
from jinja2 import pass_context
|
from jinja2 import pass_context
|
||||||
|
|
||||||
import aurweb.config
|
import aurweb.config
|
||||||
|
@ -88,7 +89,7 @@ def migrate_cookies(request, response):
|
||||||
secure_cookies = aurweb.config.getboolean("options", "disable_http_login")
|
secure_cookies = aurweb.config.getboolean("options", "disable_http_login")
|
||||||
for k, v in request.cookies.items():
|
for k, v in request.cookies.items():
|
||||||
response.set_cookie(k, v, secure=secure_cookies, httponly=True)
|
response.set_cookie(k, v, secure=secure_cookies, httponly=True)
|
||||||
return response
|
return add_samesite_fields(response, "strict")
|
||||||
|
|
||||||
|
|
||||||
@pass_context
|
@pass_context
|
||||||
|
@ -136,3 +137,15 @@ def jsonify(obj):
|
||||||
if isinstance(obj, datetime):
|
if isinstance(obj, datetime):
|
||||||
obj = int(obj.timestamp())
|
obj = int(obj.timestamp())
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def add_samesite_fields(response: Response, value: str):
|
||||||
|
""" Set the SameSite field on all cookie headers found.
|
||||||
|
Taken from https://github.com/tiangolo/fastapi/issues/1099. """
|
||||||
|
for idx, header in enumerate(response.raw_headers):
|
||||||
|
if header[0].decode() == "set-cookie":
|
||||||
|
cookie = header[1].decode()
|
||||||
|
if f"SameSite={value}" not in cookie:
|
||||||
|
cookie += f"; SameSite={value}"
|
||||||
|
response.raw_headers[idx] = (header[0], cookie.encode())
|
||||||
|
return response
|
||||||
|
|
|
@ -111,6 +111,8 @@ def test_secure_login(mock):
|
||||||
cookie = next(c for c in response.cookies if c.name == "AURSID")
|
cookie = next(c for c in response.cookies if c.name == "AURSID")
|
||||||
assert cookie.secure is True
|
assert cookie.secure is True
|
||||||
assert cookie.has_nonstandard_attr("HttpOnly") is True
|
assert cookie.has_nonstandard_attr("HttpOnly") is True
|
||||||
|
assert cookie.has_nonstandard_attr("SameSite") is True
|
||||||
|
assert cookie.get_nonstandard_attr("SameSite") == "strict"
|
||||||
assert cookie.value is not None and len(cookie.value) > 0
|
assert cookie.value is not None and len(cookie.value) > 0
|
||||||
|
|
||||||
# Let's make sure we actually have a session relationship
|
# Let's make sure we actually have a session relationship
|
||||||
|
|
Loading…
Add table
Reference in a new issue