From 7b9281803777ca154c38d248072bdd0d97f10fb4 Mon Sep 17 00:00:00 2001 From: bashrc Date: Sat, 18 Jul 2026 19:32:41 +0100 Subject: [PATCH] Return feature authorization verification --- src/daemon_get.py | 20 +++++++++++ src/daemon_get_collections.py | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/daemon_get.py b/src/daemon_get.py index 3d6218f9e..2c72cadae 100644 --- a/src/daemon_get.py +++ b/src/daemon_get.py @@ -211,6 +211,7 @@ from src.daemon_get_post import show_conversation_thread from src.daemon_get_collections import get_featured_collection from src.daemon_get_collections import get_featured_tags_collection from src.daemon_get_collections import get_following_json +from src.daemon_get_collections import get_feature_authorization from src.daemon_get_webfinger import get_webfinger from src.daemon_get_reactions import reaction_picker2 from src.daemon_get_instance_actor import show_instance_actor @@ -1872,6 +1873,25 @@ def daemon_http_get(self) -> None: self.server.yggdrasil_domain) return + if not html_getreq and \ + users_in_path and '/stamps/' in self.path: + nickname = self.path.split('/users/')[1] + if '/' in nickname: + nickname = nickname.split('/')[0] + # return the feature authorization stamp + # See verification section of + # https://codeberg.org/fediverse/fep/src/branch/main + # /fep/7aa9/fep-7aa9.md + get_feature_authorization(self, calling_domain, referer_domain, + self.server.base_dir, + self.server.http_prefix, + nickname, self.server.domain, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain, + self.server.yggdrasil_domain) + return + if not html_getreq and \ users_in_path and self.path.endswith('/collections/featuredTags'): get_featured_tags_collection(self, calling_domain, referer_domain, diff --git a/src/daemon_get_collections.py b/src/daemon_get_collections.py index 9abe0ffac..76243d8a5 100644 --- a/src/daemon_get_collections.py +++ b/src/daemon_get_collections.py @@ -15,7 +15,69 @@ from src.httpheaders import set_headers from src.posts import json_pin_post from src.utils import convert_domains from src.utils import get_json_content_from_accept +from src.utils import acct_dir +from src.utils import load_json from src.follow import get_following_feed +from src.data import is_a_file + + +def get_feature_authorization(self, calling_domain: str, + referer_domain: str, + base_dir: str, + http_prefix: str, + nickname: str, domain: str, + domain_full: str, + onion_domain: str, + i2p_domain: str, + yggdrasil_domain: str) -> None: + """Returns the verification stamp for feature authorization + https://codeberg.org/fediverse/fep/src/branch/main/fep/7aa9/fep-7aa9.md + """ + stamp_number = self.path.split('/stamps/')[1] + if '/' in stamp_number: + stamp_number = stamp_number.split('/')[0] + if not stamp_number: + return + if not stamp_number.isdigit(): + return + # does the stamp exist? + account_dir = acct_dir(base_dir, nickname, domain) + stamp_filename = account_dir + '/stamps/' + stamp_number + if not is_a_file(stamp_filename): + return + # load the stamp from file + stamp_json = load_json(stamp_filename) + if not stamp_json: + return + if not stamp_json.get('id') or not stamp_json.get('object'): + return + # create the verification + stamp_url = \ + http_prefix + '://' + domain_full + '/users/' + nickname + \ + '/stamps/' + stamp_number + verification_json = { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://gotosocial.org/ns", + "https://w3id.org/fep/7aa9" + ], + "id": stamp_url, + "type": "FeatureAuthorization", + "interactingObject": stamp_json['id'], + "interactionTarget": stamp_json['object'] + } + # send the verification + msg_str = json.dumps(verification_json, ensure_ascii=False) + msg_str = convert_domains(calling_domain, referer_domain, + msg_str, http_prefix, + domain, onion_domain, i2p_domain, + yggdrasil_domain) + msg = msg_str.encode('utf-8') + msglen = len(msg) + accept_str = self.headers['Accept'] + protocol_str = get_json_content_from_accept(accept_str) + set_headers(self, protocol_str, msglen, None, calling_domain, False) + write2(self, msg) def get_featured_collection(self, calling_domain: str,