Tweak remote instance redirection
parent
9db7bdf0fb
commit
0c5ce67d4e
40
app/main.py
40
app/main.py
|
@ -1,5 +1,4 @@
|
||||||
import base64
|
import base64
|
||||||
import html
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
@ -39,7 +38,6 @@ from starlette.background import BackgroundTask
|
||||||
from starlette.datastructures import Headers
|
from starlette.datastructures import Headers
|
||||||
from starlette.datastructures import MutableHeaders
|
from starlette.datastructures import MutableHeaders
|
||||||
from starlette.exceptions import HTTPException as StarletteHTTPException
|
from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||||
from starlette.responses import HTMLResponse
|
|
||||||
from starlette.responses import JSONResponse
|
from starlette.responses import JSONResponse
|
||||||
from starlette.types import Message
|
from starlette.types import Message
|
||||||
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware # type: ignore
|
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware # type: ignore
|
||||||
|
@ -256,7 +254,11 @@ class ActivityPubResponse(JSONResponse):
|
||||||
media_type = "application/activity+json"
|
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.
|
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.
|
since our CSP policy disallows remote form submission.
|
||||||
https://github.com/w3c/webappsec-csp/issues/8#issuecomment-810108984
|
https://github.com/w3c/webappsec-csp/issues/8#issuecomment-810108984
|
||||||
"""
|
"""
|
||||||
|
return await templates.render_template(
|
||||||
def __init__(
|
db_session,
|
||||||
self,
|
request,
|
||||||
url: str,
|
"redirect_to_remote_instance.html",
|
||||||
) -> None:
|
{
|
||||||
super().__init__(
|
"request": request,
|
||||||
content=f'<a href="{html.escape(url)}">Continue to remote resource</a>',
|
"url": url,
|
||||||
|
},
|
||||||
headers={"Refresh": "0;url=" + url},
|
headers={"Refresh": "0;url=" + url},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -980,9 +983,10 @@ async def get_remote_follow(
|
||||||
@app.post("/remote_follow")
|
@app.post("/remote_follow")
|
||||||
async def post_remote_follow(
|
async def post_remote_follow(
|
||||||
request: Request,
|
request: Request,
|
||||||
|
db_session: AsyncSession = Depends(get_db_session),
|
||||||
csrf_check: None = Depends(verify_csrf_token),
|
csrf_check: None = Depends(verify_csrf_token),
|
||||||
profile: str = Form(),
|
profile: str = Form(),
|
||||||
) -> HTMLRedirectResponse:
|
) -> templates.TemplateResponse:
|
||||||
if not profile.startswith("@"):
|
if not profile.startswith("@"):
|
||||||
profile = f"@{profile}"
|
profile = f"@{profile}"
|
||||||
|
|
||||||
|
@ -991,7 +995,9 @@ async def post_remote_follow(
|
||||||
# TODO(ts): error message to user
|
# TODO(ts): error message to user
|
||||||
raise HTTPException(status_code=404)
|
raise HTTPException(status_code=404)
|
||||||
|
|
||||||
return HTMLRedirectResponse(
|
return await redirect_to_remote_instance(
|
||||||
|
request,
|
||||||
|
db_session,
|
||||||
remote_follow_template.format(uri=ID),
|
remote_follow_template.format(uri=ID),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1020,10 +1026,11 @@ async def remote_interaction(
|
||||||
@app.post("/remote_interaction")
|
@app.post("/remote_interaction")
|
||||||
async def post_remote_interaction(
|
async def post_remote_interaction(
|
||||||
request: Request,
|
request: Request,
|
||||||
|
db_session: AsyncSession = Depends(get_db_session),
|
||||||
csrf_check: None = Depends(verify_csrf_token),
|
csrf_check: None = Depends(verify_csrf_token),
|
||||||
profile: str = Form(),
|
profile: str = Form(),
|
||||||
ap_id: str = Form(),
|
ap_id: str = Form(),
|
||||||
) -> RedirectResponse:
|
) -> templates.TemplateResponse:
|
||||||
if not profile.startswith("@"):
|
if not profile.startswith("@"):
|
||||||
profile = f"@{profile}"
|
profile = f"@{profile}"
|
||||||
|
|
||||||
|
@ -1032,9 +1039,10 @@ async def post_remote_interaction(
|
||||||
# TODO(ts): error message to user
|
# TODO(ts): error message to user
|
||||||
raise HTTPException(status_code=404)
|
raise HTTPException(status_code=404)
|
||||||
|
|
||||||
return RedirectResponse(
|
return await redirect_to_remote_instance(
|
||||||
remote_follow_template.format(uri=ap_id),
|
request,
|
||||||
status_code=302,
|
db_session,
|
||||||
|
remote_follow_template.format(uri=ID),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ async def render_template(
|
||||||
template: str,
|
template: str,
|
||||||
template_args: dict[str, Any] | None = None,
|
template_args: dict[str, Any] | None = None,
|
||||||
status_code: int = 200,
|
status_code: int = 200,
|
||||||
|
headers: dict[str, str] | None = None,
|
||||||
) -> TemplateResponse:
|
) -> TemplateResponse:
|
||||||
if template_args is None:
|
if template_args is None:
|
||||||
template_args = {}
|
template_args = {}
|
||||||
|
@ -129,6 +130,7 @@ async def render_template(
|
||||||
**template_args,
|
**template_args,
|
||||||
},
|
},
|
||||||
status_code=status_code,
|
status_code=status_code,
|
||||||
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 %}
|
Loading…
Reference in New Issue