mirror of
				https://git.sr.ht/~tsileo/microblog.pub
				synced 2025-06-05 21:59:23 +02:00 
			
		
		
		
	Tweak remote instance redirection
This commit is contained in:
		
							
								
								
									
										44
									
								
								app/main.py
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								app/main.py
									
									
									
									
									
								
							@@ -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,15 +266,16 @@ 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>',
 | 
			
		||||
            headers={"Refresh": "0;url=" + url},
 | 
			
		||||
        )
 | 
			
		||||
    return await templates.render_template(
 | 
			
		||||
        db_session,
 | 
			
		||||
        request,
 | 
			
		||||
        "redirect_to_remote_instance.html",
 | 
			
		||||
        {
 | 
			
		||||
            "request": request,
 | 
			
		||||
            "url": url,
 | 
			
		||||
        },
 | 
			
		||||
        headers={"Refresh": "0;url=" + url},
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.get(config.NavBarItems.NOTES_PATH)
 | 
			
		||||
@@ -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),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								app/templates/redirect_to_remote_instance.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/templates/redirect_to_remote_instance.html
									
									
									
									
									
										Normal 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 %}
 | 
			
		||||
		Reference in New Issue
	
	Block a user