diff --git a/src/BirdsiteLive.Domain/ActivityPubService.cs b/src/BirdsiteLive.Domain/ActivityPubService.cs index c460a2d..7a9aeeb 100644 --- a/src/BirdsiteLive.Domain/ActivityPubService.cs +++ b/src/BirdsiteLive.Domain/ActivityPubService.cs @@ -16,12 +16,19 @@ namespace BirdsiteLive.Domain { public interface IActivityPubService { + Task GetUserIdAsync(string acct); Task GetUser(string objectId); Task PostDataAsync(T data, string targetHost, string actorUrl, string inbox = null); Task PostNewNoteActivity(Note note, string username, string noteId, string targetHost, string targetInbox); } + public class WebFinger + { + public string subject { get; set; } + public string[] aliases { get; set; } + } + public class ActivityPubService : IActivityPubService { private readonly InstanceSettings _instanceSettings; @@ -39,6 +46,24 @@ namespace BirdsiteLive.Domain } #endregion + public async Task GetUserIdAsync(string acct) + { + var splittedAcct = acct.Trim('@').Split('@'); + + var url = $"https://{splittedAcct[1]}/.well-known/webfinger?resource=acct:{splittedAcct[0]}@{splittedAcct[1]}"; + + var httpClient = _httpClientFactory.CreateClient(); + httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); + var result = await httpClient.GetAsync(url); + + result.EnsureSuccessStatusCode(); + + var content = await result.Content.ReadAsStringAsync(); + + var actor = JsonConvert.DeserializeObject(content); + return actor.aliases.FirstOrDefault(); + } + public async Task GetUser(string objectId) { var httpClient = _httpClientFactory.CreateClient(); diff --git a/src/BirdsiteLive.Domain/MigrationService.cs b/src/BirdsiteLive.Domain/MigrationService.cs index 2e4a1d5..d8818dc 100644 --- a/src/BirdsiteLive.Domain/MigrationService.cs +++ b/src/BirdsiteLive.Domain/MigrationService.cs @@ -10,11 +10,13 @@ namespace BirdsiteLive.Domain public class MigrationService { private readonly ITwitterTweetsService _twitterTweetsService; + private readonly IActivityPubService _activityPubService; #region Ctor - public MigrationService(ITwitterTweetsService twitterTweetsService) + public MigrationService(ITwitterTweetsService twitterTweetsService, IActivityPubService activityPubService) { _twitterTweetsService = twitterTweetsService; + _activityPubService = activityPubService; } #endregion @@ -52,11 +54,23 @@ namespace BirdsiteLive.Domain public async Task ValidateFediverseAcctAsync(string fediverseAcct) { - return true; + if (string.IsNullOrWhiteSpace(fediverseAcct)) + throw new ArgumentException("Please provide Fediverse account"); + + if( !fediverseAcct.Contains('@') || fediverseAcct.Trim('@').Split('@').Length != 2) + throw new ArgumentException("Please provide valid Fediverse handle"); + + var objectId = await _activityPubService.GetUserIdAsync(fediverseAcct); + var user = await _activityPubService.GetUser(objectId); + + if(user != null) return true; + + return false; } public async Task MigrateAccountAsync(string acct, string tweetId, string fediverseAcct, bool triggerRemoteMigration) { + throw new NotImplementedException("Migration not implemented"); } private byte[] GetHash(string inputString)