decentralized and customizable links page on top of atproto

refuse to serve blocked did profile

Changed files
+46 -9
src
atproto
static
templates
+4 -5
src/atproto/__init__.py
··· 1 - from dns.resolver import resolve as resolve_dns, NXDOMAIN 1 + import dns.resolver as dns 2 + import httpx 2 3 from re import match as regex_match 3 4 from typing import Any 4 - import httpx 5 5 6 6 from .kv import KV, nokv 7 - 8 7 from .validator import is_valid_authserver_meta 9 8 from ..security import is_safe_url 10 9 ··· 96 95 return did 97 96 98 97 try: 99 - answer = resolve_dns(f"_atproto.{handle}", "TXT") 100 - except NXDOMAIN: 98 + answer = dns.resolve(f"_atproto.{handle}", "TXT") 99 + except dns.NXDOMAIN: 101 100 return None 102 101 103 102 for record in answer:
+12 -4
src/main.py
··· 45 45 def page_profile_with_did(did: str): 46 46 did = f"did:{did}" 47 47 if not is_valid_did(did): 48 - return "invalid did", 400 48 + return render_template("error.html", message="invalid did"), 400 49 49 return page_profile(did) 50 50 51 51 ··· 55 55 kv = KV(app, "did_from_handle") 56 56 did = resolve_did_from_handle(handle, kv, reload=reload) 57 57 if did is None: 58 - return "did not found", 404 58 + return render_template("error.html", message="did not found"), 404 59 59 return page_profile(did, reload=reload) 60 60 61 61 62 62 def page_profile(did: str, reload: bool = False): 63 + if _is_did_blocked(did): 64 + app.logger.debug(f"handling blocked did {did}") 65 + return render_template("error.html", message="profile not found"), 404 63 66 kv = KV(app, "pds_from_did") 64 67 pds = resolve_pds_from_did(did, kv, reload=reload) 65 68 if pds is None: 66 - return "pds not found", 404 69 + return render_template("error.html", message="pds not found"), 404 67 70 profile, _ = load_profile(pds, did, reload=reload) 68 71 links = load_links(pds, did, reload=reload) 69 72 if links is None: 70 - return "profile not found", 404 73 + return render_template("error.html", message="profile not found"), 404 71 74 72 75 if reload: 73 76 # remove the ?reload parameter ··· 265 268 ) 266 269 if not response or not response.is_success: 267 270 app.logger.warning("PDS HTTP ERROR") 271 + 272 + 273 + def _is_did_blocked(did: str) -> bool: 274 + kv = KV(app, "blockeddids") 275 + return kv.get(did) is not None
+4
src/static/style.css
··· 49 49 max-width: 25rem; 50 50 } 51 51 52 + .wrapper.error p { 53 + text-align: center; 54 + } 55 + 52 56 header { 53 57 margin: 2.5em 0; 54 58 text-align: center;
+26
src/templates/error.html
··· 1 + <!doctype html> 2 + <html> 3 + <head> 4 + <meta charset="utf-8" /> 5 + <title>not found &mdash; ligo.at</title> 6 + <meta name="viewport" content="width=device-width, initial-scale=1" /> 7 + <link rel="stylesheet" href="{{ url_for('static', filename='inter.css') }}" /> 8 + <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" /> 9 + <link rel="icon" type="image/png" sizes="16x16" href="{{ url_for('static', filename='favicon-16.png') }}" /> 10 + <link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', filename='favicon-32.png') }}" /> 11 + <link rel="icon" type="image/png" sizes="48x48" href="{{ url_for('static', filename='favicon-48.png') }}" /> 12 + </head> 13 + <body> 14 + <div class="wrapper error"> 15 + <header> 16 + <h1>oops!</h1> 17 + </header> 18 + <p>{{ message }}</p> 19 + <footer> 20 + <a href="/">home</a> 21 + <span>·</span> 22 + Made by <a href="/@nauta.one">@nauta.one</a> 23 + </footer> 24 + </div> 25 + </body> 26 + </html>