first draft of ActivityPub webfinger

This commit is contained in:
jesopo 2019-09-10 15:40:01 +01:00
parent 8d8d9219b8
commit 90d0452bfd
2 changed files with 52 additions and 5 deletions

View file

@ -14,10 +14,17 @@ def _parse_username(s):
if username.startswith("@"): if username.startswith("@"):
username = username[1:] username = username[1:]
if username and instance: if username and instance:
return username, instance
return None, None
def _format_username(username, instance):
return "@%s@%s" % (username, instance) return "@%s@%s" % (username, instance)
def _setting_parse(s):
username, instance = _parse_username(s)
if username and instance:
return _format_username(username, instance)
return None return None
@utils.export("set", utils.FunctionSetting(_parse_username, "fediverse", @utils.export("set", utils.FunctionSetting(_setting_parse, "fediverse",
help="Set your fediverse account", example="@gargron@mastodon.social")) help="Set your fediverse account", example="@gargron@mastodon.social"))
class Module(ModuleManager.BaseModule): class Module(ModuleManager.BaseModule):
_name = "Fedi" _name = "Fedi"
@ -41,8 +48,7 @@ class Module(ModuleManager.BaseModule):
username = None username = None
instance = None instance = None
if account: if account:
account = account.lstrip("@") username, instance = _parse_username(account)
username, _, instance = account.partition("@")
if not username or not instance: if not username or not instance:
raise utils.EventError("Please provide @<user>@<instance>") raise utils.EventError("Please provide @<user>@<instance>")
@ -129,3 +135,31 @@ class Module(ModuleManager.BaseModule):
event["stdout"].write("%s: %s - %s" % (preferred_username, event["stdout"].write("%s: %s - %s" % (preferred_username,
content, shorturl)) content, shorturl))
@utils.hook("api.get.ap-webfinger")
@utils.kwarg("authenticated", False)
def webfinger(self, event):
our_username = self.bot.get_setting("fediverse", None)
our_username, our_instance = _parse_username(our_username)
resource = event["params"].get("resource", None)
if resource and resource.startswith("acct:"):
request = resource.split(":", 1)[1]
requested_username, requested_instance = _parse_username(request)
if (requested_username == our_username and
requested_instance == our_instance):
event["response"].content_type = "application/jrd+json"
location = "https://%s" % event["url_for"]("api", "ap-user",
{"u": our_username})
event["response"].write_json({
"aliases": [location],
"links": [{
"href": location,
"rel": "self",
"type": ACTIVITY_TYPE
}],
"subject": resouce
})

View file

@ -75,6 +75,19 @@ class Handler(http.server.BaseHTTPRequestHandler):
def _minify_setting(self): def _minify_setting(self):
return _bot.get_setting("rest-api-minify", False) return _bot.get_setting("rest-api-minify", False)
def url_for(self, headers, route, endpoint, get_params={}):
hostname = headers.get("Host", None)
if not hostname:
return None
else:
get_params_str = ""
if get_params:
get_params = "?%s" % urllib.parse.urlencode(get_params)
return "%s/%s/%s%s" % (hostname, route, endpoint, get_params_str)
def _url_for(self, headers):
return lambda route, endpoint, get_params={}: self.url_for(
headers, route, endpoint, get_params)
def _handle(self, method, path, endpoint, args): def _handle(self, method, path, endpoint, args):
headers = utils.CaseInsensitiveDict(dict(self.headers.items())) headers = utils.CaseInsensitiveDict(dict(self.headers.items()))
params = self._url_params() params = self._url_params()
@ -103,7 +116,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
event_response = _events.on("api").on(method).on( event_response = _events.on("api").on(method).on(
endpoint).call_for_result_unsafe(params=params, endpoint).call_for_result_unsafe(params=params,
path=args, data=data, headers=headers, path=args, data=data, headers=headers,
response=response) response=response, url_for=self._url_for(headers))
except Exception as e: except Exception as e:
_log.error("failed to call API endpoint \"%s\"", _log.error("failed to call API endpoint \"%s\"",
[path], exc_info=True) [path], exc_info=True)