diff --git a/src/BirdsiteLive.Domain/UserService.cs b/src/BirdsiteLive.Domain/UserService.cs index f5ae123..d225888 100644 --- a/src/BirdsiteLive.Domain/UserService.cs +++ b/src/BirdsiteLive.Domain/UserService.cs @@ -11,6 +11,7 @@ using BirdsiteLive.ActivityPub.Models; using BirdsiteLive.Common.Regexes; using BirdsiteLive.Common.Settings; using BirdsiteLive.Cryptography; +using BirdsiteLive.DAL.Models; using BirdsiteLive.Domain.BusinessUseCases; using BirdsiteLive.Domain.Repository; using BirdsiteLive.Domain.Statistics; @@ -24,7 +25,7 @@ namespace BirdsiteLive.Domain { public interface IUserService { - Actor GetUser(TwitterUser twitterUser); + Actor GetUser(TwitterUser twitterUser, SyncTwitterUser dbTwitterUser); Task FollowRequestedAsync(string signature, string method, string path, string queryString, Dictionary requestHeaders, ActivityFollow activity, string body); Task UndoFollowRequestedAsync(string signature, string method, string path, string queryString, Dictionary requestHeaders, ActivityUndoFollow activity, string body); @@ -64,7 +65,7 @@ namespace BirdsiteLive.Domain } #endregion - public Actor GetUser(TwitterUser twitterUser) + public Actor GetUser(TwitterUser twitterUser, SyncTwitterUser dbTwitterUser) { var actorUrl = UrlFactory.GetActorUrl(_instanceSettings.Domain, twitterUser.Acct); var acct = twitterUser.Acct.ToLowerInvariant(); @@ -112,7 +113,7 @@ namespace BirdsiteLive.Domain new UserAttachment { type = "PropertyValue", - name = "Official", + name = "Official Account", value = $"https://twitter.com/{acct}" }, new UserAttachment @@ -120,12 +121,19 @@ namespace BirdsiteLive.Domain type = "PropertyValue", name = "Disclaimer", value = "This is an automatically created and managed mirror profile from Twitter. While it reflects exactly the content of the original account, it doesn't provide support for interactions and replies. It is an equivalent view from other 3rd party Twitter client apps and uses the same technical means to provide it." + }, + new UserAttachment + { + type = "PropertyValue", + name = "Take control of the account", + value = $"https://{_instanceSettings.Domain}" } }, endpoints = new EndPoints { sharedInbox = $"https://{_instanceSettings.Domain}/inbox" - } + }, + movedTo = dbTwitterUser?.MovedTo }; return user; } diff --git a/src/BirdsiteLive/Controllers/UsersController.cs b/src/BirdsiteLive/Controllers/UsersController.cs index 24a9eb5..0097bf9 100644 --- a/src/BirdsiteLive/Controllers/UsersController.cs +++ b/src/BirdsiteLive/Controllers/UsersController.cs @@ -11,6 +11,8 @@ using BirdsiteLive.ActivityPub; using BirdsiteLive.ActivityPub.Models; using BirdsiteLive.Common.Regexes; using BirdsiteLive.Common.Settings; +using BirdsiteLive.DAL.Contracts; +using BirdsiteLive.DAL.Models; using BirdsiteLive.Domain; using BirdsiteLive.Models; using BirdsiteLive.Tools; @@ -28,13 +30,14 @@ namespace BirdsiteLive.Controllers { private readonly ITwitterUserService _twitterUserService; private readonly ITwitterTweetsService _twitterTweetService; + private readonly ITwitterUserDal _twitterUserDal; private readonly IUserService _userService; private readonly IStatusService _statusService; private readonly InstanceSettings _instanceSettings; 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, ILogger logger, ITwitterUserDal twitterUserDal) { _twitterUserService = twitterUserService; _userService = userService; @@ -42,6 +45,7 @@ namespace BirdsiteLive.Controllers _instanceSettings = instanceSettings; _twitterTweetService = twitterTweetService; _logger = logger; + _twitterUserDal = twitterUserDal; } #endregion @@ -60,7 +64,7 @@ namespace BirdsiteLive.Controllers [Route("/@{id}")] [Route("/users/{id}")] [Route("/users/{id}/remote_follow")] - public IActionResult Index(string id) + public async Task Index(string id) { _logger.LogTrace("User Index: {Id}", id); @@ -102,6 +106,7 @@ namespace BirdsiteLive.Controllers } //var isSaturated = _twitterUserService.IsUserApiRateLimited(); + var dbUser = await _twitterUserDal.GetTwitterUserAsync(id); var acceptHeaders = Request.Headers["Accept"]; if (acceptHeaders.Any()) @@ -111,7 +116,8 @@ namespace BirdsiteLive.Controllers { if (isSaturated) return new ObjectResult("Too Many Requests") { StatusCode = 429 }; if (notFound) return NotFound(); - var apUser = _userService.GetUser(user); + if (dbUser != null && dbUser.Deleted) return NotFound(); + var apUser = _userService.GetUser(user, dbUser); var jsonApUser = JsonConvert.SerializeObject(apUser); return Content(jsonApUser, "application/activity+json; charset=utf-8"); } @@ -128,8 +134,12 @@ namespace BirdsiteLive.Controllers Url = user.Url, ProfileImageUrl = user.ProfileImageUrl, Protected = user.Protected, + + InstanceHandle = $"@{user.Acct.ToLowerInvariant()}@{_instanceSettings.Domain}", - InstanceHandle = $"@{user.Acct.ToLowerInvariant()}@{_instanceSettings.Domain}" + MovedTo = dbUser?.MovedTo, + MovedToAcct = dbUser?.MovedToAcct, + Deleted = dbUser?.Deleted ?? false, }; return View(displayableUser); } diff --git a/src/BirdsiteLive/Models/DisplayTwitterUser.cs b/src/BirdsiteLive/Models/DisplayTwitterUser.cs index 3a93875..0b17174 100644 --- a/src/BirdsiteLive/Models/DisplayTwitterUser.cs +++ b/src/BirdsiteLive/Models/DisplayTwitterUser.cs @@ -10,5 +10,9 @@ public bool Protected { get; set; } public string InstanceHandle { get; set; } + + public string MovedTo { get; set; } + public string MovedToAcct { get; set; } + public bool Deleted { get; set; } } } \ No newline at end of file diff --git a/src/BirdsiteLive/Views/Users/Index.cshtml b/src/BirdsiteLive/Views/Users/Index.cshtml index 96ae0d4..48d626d 100644 --- a/src/BirdsiteLive/Views/Users/Index.cshtml +++ b/src/BirdsiteLive/Views/Users/Index.cshtml @@ -37,6 +37,19 @@ This account is protected, BirdsiteLIVE cannot fetch their tweets and will not provide follow support until it is unprotected again. } + else if (ViewData.Model.Deleted) + { + + } + else if (!string.IsNullOrEmpty(ViewData.Model.MovedTo)) + { + + } else {
@@ -46,7 +59,10 @@
} - + @if (!ViewData.Model.Deleted && string.IsNullOrEmpty(ViewData.Model.MovedTo)) + { + + } \ No newline at end of file