From af8345d8c9626e196655942294d39ae8c9e60a45 Mon Sep 17 00:00:00 2001 From: Miss Pasture Date: Sat, 17 Jul 2021 20:26:45 -0400 Subject: [PATCH] Remote follow --- .../Models/WebFingerData.cs | 21 ++++++++ src/BirdsiteLive.Domain/ActivityPubService.cs | 10 ++++ .../Controllers/UsersController.cs | 50 ++++++++++++++++++- src/BirdsiteLive/Views/Users/Index.cshtml | 7 ++- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/BirdsiteLive.ActivityPub/Models/WebFingerData.cs diff --git a/src/BirdsiteLive.ActivityPub/Models/WebFingerData.cs b/src/BirdsiteLive.ActivityPub/Models/WebFingerData.cs new file mode 100644 index 0000000..31dc1b8 --- /dev/null +++ b/src/BirdsiteLive.ActivityPub/Models/WebFingerData.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace BirdsiteLive.ActivityPub.Models +{ + public class WebFingerData + { + public List aliases { get; set; } + + public List links { get; set; } + } + + public class WebFingerLink + { + public string href { get; set; } + public string rel { get; set; } + public string type { get; set; } + public string template { get; set; } + } +} diff --git a/src/BirdsiteLive.Domain/ActivityPubService.cs b/src/BirdsiteLive.Domain/ActivityPubService.cs index 37fe0b5..71a1457 100644 --- a/src/BirdsiteLive.Domain/ActivityPubService.cs +++ b/src/BirdsiteLive.Domain/ActivityPubService.cs @@ -21,6 +21,7 @@ namespace BirdsiteLive.Domain Task PostDataAsync(T data, string targetHost, string actorUrl, string inbox = null); Task PostNewNoteActivity(Note note, string username, string noteId, string targetHost, string targetInbox); + Task WebFinger(string account); } public class ActivityPubService : IActivityPubService @@ -118,5 +119,14 @@ namespace BirdsiteLive.Domain response.EnsureSuccessStatusCode(); return response.StatusCode; } + + public async Task WebFinger(string account) + { + var httpClient = _httpClientFactory.CreateClient(); + var result = await httpClient.GetAsync("https://" + account.Split('@')[1] + "/.well-known/webfinger?resource=acct:" + account); + var content = await result.Content.ReadAsStringAsync(); + + return JsonConvert.DeserializeObject(content); + } } } \ No newline at end of file diff --git a/src/BirdsiteLive/Controllers/UsersController.cs b/src/BirdsiteLive/Controllers/UsersController.cs index 91b63c7..753a141 100644 --- a/src/BirdsiteLive/Controllers/UsersController.cs +++ b/src/BirdsiteLive/Controllers/UsersController.cs @@ -30,16 +30,18 @@ namespace BirdsiteLive.Controllers private readonly IUserService _userService; private readonly IStatusService _statusService; private readonly InstanceSettings _instanceSettings; + private readonly IActivityPubService _activityPubService; private readonly ILogger _logger; #region Ctor - public UsersController(ITwitterUserService twitterUserService, IUserService userService, IStatusService statusService, InstanceSettings instanceSettings, ITwitterTweetsService twitterTweetService, ILogger logger) + public UsersController(ITwitterUserService twitterUserService, IUserService userService, IStatusService statusService, InstanceSettings instanceSettings, ITwitterTweetsService twitterTweetService, IActivityPubService activityPubService, ILogger logger) { _twitterUserService = twitterUserService; _userService = userService; _statusService = statusService; _instanceSettings = instanceSettings; _twitterTweetService = twitterTweetService; + _activityPubService = activityPubService; _logger = logger; } #endregion @@ -188,5 +190,51 @@ namespace BirdsiteLive.Controllers { return header.ToDictionary, string, string>(h => h.Key.ToLowerInvariant(), h => h.Value); } + + [Route("/users/{actor}/remote_follow")] + [HttpPost] + public async Task RemoteFollow(string actor) + { + StringValues webfingerValues; + + if (!Request.Form.TryGetValue("webfinger", out webfingerValues)) return BadRequest(); + + var webfinger = webfingerValues.First(); + + if (webfinger.Length < 1 || actor.Length < 1) return BadRequest(); + + if (webfinger[0] == '@') webfinger = webfinger[1..]; + + if (webfinger.IndexOf("@") < 0 || ! new Regex("^[A-Za-z0-9_]*$").IsMatch(webfinger.Split('@')[0]) || ! new Regex("^[A-Za-z0-9_]*$").IsMatch(actor) || Uri.CheckHostName(webfinger.Split('@')[1]) == UriHostNameType.Unknown) + { + return BadRequest(); + } + + WebFingerData webfingerData; + + try + { + webfingerData = await _activityPubService.WebFinger(webfinger); + } + catch(Exception e) + { + _logger.LogError("Could not WebFinger {user}: {exception}", webfinger, e); + return NotFound(); + } + + string redirectLink = ""; + + foreach(var link in webfingerData.links) + { + if(link.rel == "http://ostatus.org/schema/1.0/subscribe" && link.template.Length > 0) + { + redirectLink = link.template.Replace("{uri}", "https://" + _instanceSettings.Domain + "/users/" + actor); + } + } + + if (redirectLink == "") return NotFound(); + + return Redirect(redirectLink); + } } } \ No newline at end of file diff --git a/src/BirdsiteLive/Views/Users/Index.cshtml b/src/BirdsiteLive/Views/Users/Index.cshtml index 945964a..d0bce7a 100644 --- a/src/BirdsiteLive/Views/Users/Index.cshtml +++ b/src/BirdsiteLive/Views/Users/Index.cshtml @@ -40,7 +40,12 @@ else {
-

Search this handle to find it in your instance:

+
+ + +
+ +

or search this handle to find it in your instance: