From 6ec6a43e1c990898c8c60d3b8aa718f539165460 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Tue, 9 Jan 2024 20:00:54 +0100 Subject: [PATCH] WIP: UserResolver --- .../Core/Federation/WebFinger/UserResolver.cs | 31 +++++++++++++++++++ .../Core/Federation/WebFinger/WebFinger.cs | 23 ++++++-------- 2 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 Iceshrimp.Backend/Core/Federation/WebFinger/UserResolver.cs diff --git a/Iceshrimp.Backend/Core/Federation/WebFinger/UserResolver.cs b/Iceshrimp.Backend/Core/Federation/WebFinger/UserResolver.cs new file mode 100644 index 00000000..a612e887 --- /dev/null +++ b/Iceshrimp.Backend/Core/Federation/WebFinger/UserResolver.cs @@ -0,0 +1,31 @@ +using Iceshrimp.Backend.Core.Database.Tables; + +namespace Iceshrimp.Backend.Core.Federation.WebFinger; + +public static class UserResolver { + private static string AcctToDomain(string acct) => + acct.StartsWith("acct:") && acct.Contains('@') + ? acct[5..].Split('@')[1] + : throw new Exception("Invalid acct"); + + /* + * Split domain logic: + * 1. Get WebFinger response for query + * 2. [...] + * TODO: finish description and implement the rest + */ + + public static async Task Resolve(string query) { + var finger = new WebFinger(query); + var fingerRes = await finger.Resolve(); + if (fingerRes == null) throw new Exception($"Failed to WebFinger '{query}'"); + if (finger.Domain != AcctToDomain(fingerRes.Subject)) { + //TODO: Logger.info("possible split domain deployment detected, repeating webfinger") + + finger = new WebFinger(fingerRes.Subject); + fingerRes = await finger.Resolve(); + } + + throw new NotImplementedException("stub method return"); + } +} \ No newline at end of file diff --git a/Iceshrimp.Backend/Core/Federation/WebFinger/WebFinger.cs b/Iceshrimp.Backend/Core/Federation/WebFinger/WebFinger.cs index 09051993..c2a15b1a 100644 --- a/Iceshrimp.Backend/Core/Federation/WebFinger/WebFinger.cs +++ b/Iceshrimp.Backend/Core/Federation/WebFinger/WebFinger.cs @@ -1,7 +1,6 @@ using System.Net.Http.Headers; using System.Text.Encodings.Web; using System.Xml; -using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Helpers; namespace Iceshrimp.Backend.Core.Federation.WebFinger; @@ -16,18 +15,21 @@ namespace Iceshrimp.Backend.Core.Federation.WebFinger; * - doesn't have a query url template */ +//FIXME: handle cursed person/group acct collisions like https://lemmy.ml/.well-known/webfinger?resource=acct:linux@lemmy.ml + public class WebFinger { private readonly string _query; private readonly string _proto; private readonly string _domain; - private readonly string? _username; private string? _webFingerUrl; + public string Domain => _domain; + private string HostMetaUrl => $"{_proto}://{_domain}/.well-known/host-meta"; private string DefaultWebFingerTemplate => $"{_proto}://{_domain}/.well-known/webfinger?resource={{uri}}"; public WebFinger(string query) { - _query = query; + _query = query.StartsWith("acct:") ? $"@{query[5..]}" : query; if (_query.StartsWith("http://") || _query.StartsWith("https://")) { var uri = new Uri(_query); _domain = uri.Host; @@ -37,17 +39,12 @@ public class WebFinger { _proto = "https"; var split = _query.Split('@'); - if (split.Length == 2) { - throw new Exception("Can't run WebFinger for local user"); - } - - if (split.Length == 3) { - _username = split[1]; - _domain = split[2]; - } - else { + if (split.Length is < 2 or > 3) throw new Exception("Invalid query"); - } + if (split.Length is 2) + throw new Exception("Can't run WebFinger for local user"); + + _domain = split[2]; } else { throw new Exception("Invalid query");