Tweak remote instance redirection

This commit is contained in:
Thomas Sileo 2022-11-13 17:37:19 +01:00
parent 9db7bdf0fb
commit 0c5ce67d4e
3 changed files with 43 additions and 18 deletions

View file

@ -1,5 +1,4 @@
import base64
import html
import os
import sys
import time
@ -39,7 +38,6 @@ from starlette.background import BackgroundTask
from starlette.datastructures import Headers
from starlette.datastructures import MutableHeaders
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.responses import HTMLResponse
from starlette.responses import JSONResponse
from starlette.types import Message
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware # type: ignore
@ -256,7 +254,11 @@ class ActivityPubResponse(JSONResponse):
media_type = "application/activity+json"
class HTMLRedirectResponse(HTMLResponse):
async def redirect_to_remote_instance(
request: Request,
db_session: AsyncSession,
url: str,
) -> templates.TemplateResponse:
"""
Similar to RedirectResponse, but uses a 200 response with HTML.
@ -264,13 +266,14 @@ class HTMLRedirectResponse(HTMLResponse):
since our CSP policy disallows remote form submission.
https://github.com/w3c/webappsec-csp/issues/8#issuecomment-810108984
"""
def __init__(
self,
url: str,
) -> None:
super().__init__(
content=f'<a href="{html.escape(url)}">Continue to remote resource</a>',
return await templates.render_template(
db_session,
request,
"redirect_to_remote_instance.html",
{
"request": request,
"url": url,
},
headers={"Refresh": "0;url=" + url},
)
@ -980,9 +983,10 @@ async def get_remote_follow(
@app.post("/remote_follow")
async def post_remote_follow(
request: Request,
db_session: AsyncSession = Depends(get_db_session),
csrf_check: None = Depends(verify_csrf_token),
profile: str = Form(),
) -> HTMLRedirectResponse:
) -> templates.TemplateResponse:
if not profile.startswith("@"):
profile = f"@{profile}"
@ -991,7 +995,9 @@ async def post_remote_follow(
# TODO(ts): error message to user
raise HTTPException(status_code=404)
return HTMLRedirectResponse(
return await redirect_to_remote_instance(
request,
db_session,
remote_follow_template.format(uri=ID),
)
@ -1020,10 +1026,11 @@ async def remote_interaction(
@app.post("/remote_interaction")
async def post_remote_interaction(
request: Request,
db_session: AsyncSession = Depends(get_db_session),
csrf_check: None = Depends(verify_csrf_token),
profile: str = Form(),
ap_id: str = Form(),
) -> RedirectResponse:
) -> templates.TemplateResponse:
if not profile.startswith("@"):
profile = f"@{profile}"
@ -1032,9 +1039,10 @@ async def post_remote_interaction(
# TODO(ts): error message to user
raise HTTPException(status_code=404)
return RedirectResponse(
remote_follow_template.format(uri=ap_id),
status_code=302,
return await redirect_to_remote_instance(
request,
db_session,
remote_follow_template.format(uri=ID),
)

View file

@ -85,6 +85,7 @@ async def render_template(
template: str,
template_args: dict[str, Any] | None = None,
status_code: int = 200,
headers: dict[str, str] | None = None,
) -> TemplateResponse:
if template_args is None:
template_args = {}
@ -129,6 +130,7 @@ async def render_template(
**template_args,
},
status_code=status_code,
headers=headers,
)

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 your instance: <a href="{{ url }}">{{ url }}</a></p>
</div>
{% endblock %}