Fix CSP IndieAuth redirection issue

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

28
app/redirect.py 100644
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 %}