added achitecture to handle Delete action
This commit is contained in:
parent
5ef8af47eb
commit
93b43ee4a0
7 changed files with 91 additions and 10 deletions
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using BirdsiteLive.ActivityPub.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BirdsiteLive.ActivityPub
|
||||
|
@ -19,6 +20,8 @@ namespace BirdsiteLive.ActivityPub
|
|||
if(a.apObject.type == "Follow")
|
||||
return JsonConvert.DeserializeObject<ActivityUndoFollow>(json);
|
||||
break;
|
||||
case "Delete":
|
||||
return JsonConvert.DeserializeObject<ActivityDelete>(json);
|
||||
case "Accept":
|
||||
var accept = JsonConvert.DeserializeObject<ActivityAccept>(json);
|
||||
//var acceptType = JsonConvert.DeserializeObject<Activity>(accept.apObject);
|
||||
|
|
10
src/BirdsiteLive.ActivityPub/Models/ActivityDelete.cs
Normal file
10
src/BirdsiteLive.ActivityPub/Models/ActivityDelete.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace BirdsiteLive.ActivityPub.Models
|
||||
{
|
||||
public class ActivityDelete : Activity
|
||||
{
|
||||
[JsonProperty("object")]
|
||||
public object apObject { get; set; }
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using BirdsiteLive.ActivityPub;
|
||||
using BirdsiteLive.ActivityPub.Converters;
|
||||
using BirdsiteLive.ActivityPub.Models;
|
||||
using BirdsiteLive.Common.Regexes;
|
||||
using BirdsiteLive.Common.Settings;
|
||||
using BirdsiteLive.Cryptography;
|
||||
|
@ -28,6 +29,7 @@ namespace BirdsiteLive.Domain
|
|||
Task<bool> UndoFollowRequestedAsync(string signature, string method, string path, string queryString, Dictionary<string, string> requestHeaders, ActivityUndoFollow activity, string body);
|
||||
|
||||
Task<bool> SendRejectFollowAsync(ActivityFollow activity, string followerHost);
|
||||
Task<bool> DeleteRequestedAsync(string signature, string method, string path, string queryString, Dictionary<string, string> requestHeaders, ActivityDelete activity, string body);
|
||||
}
|
||||
|
||||
public class UserService : IUserService
|
||||
|
@ -213,7 +215,7 @@ namespace BirdsiteLive.Domain
|
|||
return result == HttpStatusCode.Accepted ||
|
||||
result == HttpStatusCode.OK; //TODO: revamp this for better error handling
|
||||
}
|
||||
|
||||
|
||||
private string OnlyKeepRoute(string inbox, string host)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(inbox))
|
||||
|
@ -258,6 +260,19 @@ namespace BirdsiteLive.Domain
|
|||
return result == HttpStatusCode.Accepted || result == HttpStatusCode.OK; //TODO: revamp this for better error handling
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteRequestedAsync(string signature, string method, string path, string queryString, Dictionary<string, string> requestHeaders,
|
||||
ActivityDelete activity, string body)
|
||||
{
|
||||
// Validate
|
||||
var sigValidation = await ValidateSignature(activity.actor, signature, method, path, queryString, requestHeaders, body);
|
||||
if (!sigValidation.SignatureIsValidated) return false;
|
||||
|
||||
// Remove user and followings
|
||||
throw new NotImplementedException();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<SignatureValidationResult> ValidateSignature(string actor, string rawSig, string method, string path, string queryString, Dictionary<string, string> requestHeaders, string body)
|
||||
{
|
||||
//Check Date Validity
|
||||
|
|
|
@ -3,6 +3,10 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BirdsiteLive.ActivityPub;
|
||||
using BirdsiteLive.ActivityPub.Models;
|
||||
using BirdsiteLive.Domain;
|
||||
using BirdsiteLive.Tools;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -13,11 +17,13 @@ namespace BirdsiteLive.Controllers
|
|||
public class InboxController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<InboxController> _logger;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
#region Ctor
|
||||
public InboxController(ILogger<InboxController> logger)
|
||||
public InboxController(ILogger<InboxController> logger, IUserService userService)
|
||||
{
|
||||
_logger = logger;
|
||||
_userService = userService;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -33,6 +39,19 @@ namespace BirdsiteLive.Controllers
|
|||
_logger.LogTrace("Inbox: {Body}", body);
|
||||
//System.IO.File.WriteAllText($@"C:\apdebug\inbox\{Guid.NewGuid()}.json", body);
|
||||
|
||||
var activity = ApDeserializer.ProcessActivity(body);
|
||||
var signature = r.Headers["Signature"].First();
|
||||
|
||||
switch (activity?.type)
|
||||
{
|
||||
case "Delete":
|
||||
{
|
||||
var succeeded = await _userService.DeleteRequestedAsync(signature, r.Method, r.Path,
|
||||
r.QueryString.ToString(), HeaderHandler.RequestHeaders(r.Headers), activity as ActivityDelete, body);
|
||||
if (succeeded) return Accepted();
|
||||
else return Unauthorized();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Accepted();
|
||||
|
|
|
@ -13,6 +13,7 @@ using BirdsiteLive.Common.Regexes;
|
|||
using BirdsiteLive.Common.Settings;
|
||||
using BirdsiteLive.Domain;
|
||||
using BirdsiteLive.Models;
|
||||
using BirdsiteLive.Tools;
|
||||
using BirdsiteLive.Twitter;
|
||||
using BirdsiteLive.Twitter.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
@ -142,7 +143,6 @@ namespace BirdsiteLive.Controllers
|
|||
//System.IO.File.WriteAllText($@"C:\apdebug\{Guid.NewGuid()}.json", body);
|
||||
|
||||
var activity = ApDeserializer.ProcessActivity(body);
|
||||
// Do something
|
||||
var signature = r.Headers["Signature"].First();
|
||||
|
||||
switch (activity?.type)
|
||||
|
@ -150,7 +150,7 @@ namespace BirdsiteLive.Controllers
|
|||
case "Follow":
|
||||
{
|
||||
var succeeded = await _userService.FollowRequestedAsync(signature, r.Method, r.Path,
|
||||
r.QueryString.ToString(), RequestHeaders(r.Headers), activity as ActivityFollow, body);
|
||||
r.QueryString.ToString(), HeaderHandler.RequestHeaders(r.Headers), activity as ActivityFollow, body);
|
||||
if (succeeded) return Accepted();
|
||||
else return Unauthorized();
|
||||
}
|
||||
|
@ -158,11 +158,18 @@ namespace BirdsiteLive.Controllers
|
|||
if (activity is ActivityUndoFollow)
|
||||
{
|
||||
var succeeded = await _userService.UndoFollowRequestedAsync(signature, r.Method, r.Path,
|
||||
r.QueryString.ToString(), RequestHeaders(r.Headers), activity as ActivityUndoFollow, body);
|
||||
r.QueryString.ToString(), HeaderHandler.RequestHeaders(r.Headers), activity as ActivityUndoFollow, body);
|
||||
if (succeeded) return Accepted();
|
||||
else return Unauthorized();
|
||||
}
|
||||
return Accepted();
|
||||
case "Delete":
|
||||
{
|
||||
var succeeded = await _userService.DeleteRequestedAsync(signature, r.Method, r.Path,
|
||||
r.QueryString.ToString(), HeaderHandler.RequestHeaders(r.Headers), activity as ActivityDelete, body);
|
||||
if (succeeded) return Accepted();
|
||||
else return Unauthorized();
|
||||
}
|
||||
default:
|
||||
return Accepted();
|
||||
}
|
||||
|
@ -184,9 +191,6 @@ namespace BirdsiteLive.Controllers
|
|||
return Content(jsonApUser, "application/activity+json; charset=utf-8");
|
||||
}
|
||||
|
||||
private Dictionary<string, string> RequestHeaders(IHeaderDictionary header)
|
||||
{
|
||||
return header.ToDictionary<KeyValuePair<string, StringValues>, string, string>(h => h.Key.ToLowerInvariant(), h => h.Value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
15
src/BirdsiteLive/Tools/HeaderHandler.cs
Normal file
15
src/BirdsiteLive/Tools/HeaderHandler.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace BirdsiteLive.Tools
|
||||
{
|
||||
public class HeaderHandler
|
||||
{
|
||||
public static Dictionary<string, string> RequestHeaders(IHeaderDictionary header)
|
||||
{
|
||||
return header.ToDictionary<KeyValuePair<string, StringValues>, string, string>(h => h.Key.ToLowerInvariant(), h => h.Value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using BirdsiteLive.ActivityPub.Models;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BirdsiteLive.ActivityPub.Tests
|
||||
|
@ -48,6 +49,20 @@ namespace BirdsiteLive.ActivityPub.Tests
|
|||
Assert.AreEqual("https://mamot.fr/users/testtest", data.apObject.apObject);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DeleteDeserializationTest()
|
||||
{
|
||||
var json =
|
||||
"{\"@context\": \"https://www.w3.org/ns/activitystreams\", \"id\": \"https://mastodon.technology/users/deleteduser#delete\", \"type\": \"Delete\", \"actor\": \"https://mastodon.technology/users/deleteduser\", \"to\": [\"https://www.w3.org/ns/activitystreams#Public\"],\"object\": \"https://mastodon.technology/users/deleteduser\",\"signature\": {\"type\": \"RsaSignature2017\",\"creator\": \"https://mastodon.technology/users/deleteduser#main-key\",\"created\": \"2020-11-19T22:43:01Z\",\"signatureValue\": \"peksQao4v5N+sMZgHXZ6xZnGaZrd0s+LqZimu63cnp7O5NBJM6gY9AAu/vKUgrh4C50r66f9OQdHg5yChQhc4ViE+yLR/3/e59YQimelmXJPpcC99Nt0YLU/iTRLsBehY3cDdC6+ogJKgpkToQvB6tG2KrPdrkreYh4Il4eXLKMfiQhgdKluOvenLnl2erPWfE02hIu/jpuljyxSuvJunMdU4yQVSZHTtk/I8q3jjzIzhgyb7ICWU5Hkx0H/47Q24ztsvOgiTWNgO+v6l9vA7qIhztENiRPhzGP5RCCzUKRAe6bcSu1Wfa3NKWqB9BeJ7s+2y2bD7ubPbiEE1MQV7Q==\"}}";
|
||||
|
||||
var data = ApDeserializer.ProcessActivity(json) as ActivityDelete;
|
||||
|
||||
Assert.AreEqual("https://mastodon.technology/users/deleteduser#delete", data.id);
|
||||
Assert.AreEqual("Delete", data.type);
|
||||
Assert.AreEqual("https://mastodon.technology/users/deleteduser", data.actor);
|
||||
Assert.AreEqual("https://mastodon.technology/users/deleteduser", data.apObject);
|
||||
}
|
||||
|
||||
//[TestMethod]
|
||||
//public void NoteDeserializationTest()
|
||||
//{
|
||||
|
|
Reference in a new issue