From 058df0ac789849174694d540817201dca3345f22 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Sun, 16 Jun 2024 08:45:14 -0400 Subject: [PATCH] properly handle non-ascii domain names * ensure domains are stored as ascii in the database * convert domains to unicode on the frontend --- pyproject.toml | 1 + relay/frontend/page/admin-domain_bans.haml | 2 +- relay/frontend/page/admin-instances.haml | 4 ++-- relay/frontend/page/admin-whitelist.haml | 2 +- relay/frontend/page/home.haml | 2 +- relay/views/api.py | 21 +++++++++++++++++++++ 6 files changed, 27 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 65a08b9..6f06de0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ dependencies = [ "barkshark-sql == 0.1.4-1", "click >= 8.1.2", "hiredis == 2.3.2", + "idna == 3.4", "jinja2-haml == 0.3.5", "markdown == 3.6", "platformdirs == 4.2.2", diff --git a/relay/frontend/page/admin-domain_bans.haml b/relay/frontend/page/admin-domain_bans.haml index 19ae4ae..b1f7f57 100644 --- a/relay/frontend/page/admin-domain_bans.haml +++ b/relay/frontend/page/admin-domain_bans.haml @@ -35,7 +35,7 @@ %tr(id="{{ban.domain}}") %td.domain %details - %summary -> =ban.domain + %summary -> =ban.domain.encode().decode("idna") .grid-2col %label.reason(for="{{ban.domain}}-reason") << Reason diff --git a/relay/frontend/page/admin-instances.haml b/relay/frontend/page/admin-instances.haml index 2e43f48..c317e30 100644 --- a/relay/frontend/page/admin-instances.haml +++ b/relay/frontend/page/admin-instances.haml @@ -39,7 +39,7 @@ -for request in requests %tr(id="{{request.domain}}") %td.instance - %a(href="https://{{request.domain}}" target="_new") -> =request.domain + %a(href="https://{{request.domain}}" target="_new") -> =request.domain.encode().decode("idna") %td.software =request.software or "n/a" @@ -69,7 +69,7 @@ -for instance in instances %tr(id="{{instance.domain}}") %td.instance - %a(href="https://{{instance.domain}}/" target="_new") -> =instance.domain + %a(href="https://{{instance.domain}}/" target="_new") -> =instance.domain.encode().decode("idna") %td.software =instance.software or "n/a" diff --git a/relay/frontend/page/admin-whitelist.haml b/relay/frontend/page/admin-whitelist.haml index f494aef..c8111e5 100644 --- a/relay/frontend/page/admin-whitelist.haml +++ b/relay/frontend/page/admin-whitelist.haml @@ -27,7 +27,7 @@ -for item in whitelist %tr(id="{{item.domain}}") %td.domain - =item.domain + =item.domain.encode().decode("idna") %td.date =item.created.strftime("%Y-%m-%d") diff --git a/relay/frontend/page/home.haml b/relay/frontend/page/home.haml index f9618fc..fa883d6 100644 --- a/relay/frontend/page/home.haml +++ b/relay/frontend/page/home.haml @@ -41,7 +41,7 @@ -for instance in instances %tr %td.instance -> %a(href="https://{{instance.domain}}/" target="_new") - =instance.domain + =instance.domain.encode().decode("idna") %td.date =instance.created.strftime("%Y-%m-%d") diff --git a/relay/views/api.py b/relay/views/api.py index 86382f4..70a9f0e 100644 --- a/relay/views/api.py +++ b/relay/views/api.py @@ -203,6 +203,8 @@ class Inbox(View): if conn.get_inbox(data['domain']): return Response.new_error(404, 'Instance already in database', 'json') + data['domain'] = data['domain'].encode('idna').decode() + if not data.get('inbox'): actor_data: Message | None = await self.client.get(data['actor'], True, Message) @@ -229,6 +231,8 @@ class Inbox(View): if isinstance(data, Response): return data + data['domain'] = data['domain'].encode('idna').decode() + if not (instance := conn.get_inbox(data['domain'])): return Response.new_error(404, 'Instance with domain not found', 'json') @@ -244,6 +248,8 @@ class Inbox(View): if isinstance(data, Response): return data + data['domain'] = data['domain'].encode('idna').decode() + if not conn.get_inbox(data['domain']): return Response.new_error(404, 'Instance with domain not found', 'json') @@ -263,7 +269,12 @@ class RequestView(View): async def post(self, request: Request) -> Response: data: dict[str, Any] | Response = await self.get_api_data(['domain', 'accept'], []) + + if isinstance(data, Response): + return data + data['accept'] = boolean(data['accept']) + data['domain'] = data['domain'].encode('idna').decode() try: with self.database.session(True) as conn: @@ -308,6 +319,8 @@ class DomainBan(View): if isinstance(data, Response): return data + data['domain'] = data['domain'].encode('idna').decode() + with self.database.session() as conn: if conn.get_domain_ban(data['domain']): return Response.new_error(400, 'Domain already banned', 'json') @@ -324,6 +337,8 @@ class DomainBan(View): if isinstance(data, Response): return data + data['domain'] = data['domain'].encode('idna').decode() + if not conn.get_domain_ban(data['domain']): return Response.new_error(404, 'Domain not banned', 'json') @@ -342,6 +357,8 @@ class DomainBan(View): if isinstance(data, Response): return data + data['domain'] = data['domain'].encode('idna').decode() + if not conn.get_domain_ban(data['domain']): return Response.new_error(404, 'Domain not banned', 'json') @@ -479,6 +496,8 @@ class Whitelist(View): if isinstance(data, Response): return data + data['domain'] = data['domain'].encode('idna').decode() + with self.database.session() as conn: if conn.get_domain_whitelist(data['domain']): return Response.new_error(400, 'Domain already added to whitelist', 'json') @@ -494,6 +513,8 @@ class Whitelist(View): if isinstance(data, Response): return data + data['domain'] = data['domain'].encode('idna').decode() + with self.database.session() as conn: if not conn.get_domain_whitelist(data['domain']): return Response.new_error(404, 'Domain not in whitelist', 'json')