Fix CSP IndieAuth redirection issue

This commit is contained in:
Thomas Sileo 2022-12-16 09:22:40 +01:00
parent 573a76c0c5
commit db6016394b
3 changed files with 47 additions and 5 deletions

View file

@ -10,7 +10,6 @@ from fastapi import Form
from fastapi import HTTPException
from fastapi import Request
from fastapi.responses import JSONResponse
from fastapi.responses import RedirectResponse
from loguru import logger
from sqlalchemy import select
@ -21,6 +20,7 @@ from app.admin import user_session_or_redirect
from app.config import verify_csrf_token
from app.database import AsyncSession
from app.database import get_db_session
from app.redirect import redirect
from app.utils import indieauth
from app.utils.datetime import now
@ -80,7 +80,7 @@ async def indieauth_flow(
db_session: AsyncSession = Depends(get_db_session),
csrf_check: None = Depends(verify_csrf_token),
_: None = Depends(user_session_or_redirect),
) -> RedirectResponse:
) -> templates.TemplateResponse:
form_data = await request.form()
logger.info(f"{form_data=}")
@ -114,9 +114,8 @@ async def indieauth_flow(
db_session.add(auth_request)
await db_session.commit()
return RedirectResponse(
redirect_uri + f"?code={code}&state={state}&iss={iss}",
status_code=302,
return await redirect(
request, db_session, redirect_uri + f"?code={code}&state={state}&iss={iss}"
)

28
app/redirect.py Normal file
View file

@ -0,0 +1,28 @@
from fastapi import Request
from app import templates
from app.database import AsyncSession
async def redirect(
request: Request,
db_session: AsyncSession,
url: str,
) -> templates.TemplateResponse:
"""
Similar to RedirectResponse, but uses a 200 response with HTML.
Needed for remote redirects on form submission endpoints,
since our CSP policy disallows remote form submission.
https://github.com/w3c/webappsec-csp/issues/8#issuecomment-810108984
"""
return await templates.render_template(
db_session,
request,
"redirect.html",
{
"request": request,
"url": url,
},
headers={"Refresh": "0;url=" + url},
)

View file

@ -0,0 +1,15 @@
{%- import "utils.html" as utils with context -%}
{% extends "layout.html" %}
{% block head %}
<title>{{ local_actor.display_name }}'s microblog - Redirect</title>
{% endblock %}
{% block content %}
{% include "header.html" %}
<div class="box">
<p>You are being redirected to: <a href="{{ url }}">{{ url }}</a></p>
</div>
{% endblock %}