diff --git a/Iceshrimp.Backend/Controllers/ActivityPubController.cs b/Iceshrimp.Backend/Controllers/ActivityPubController.cs index 000d0268..bf151c64 100644 --- a/Iceshrimp.Backend/Controllers/ActivityPubController.cs +++ b/Iceshrimp.Backend/Controllers/ActivityPubController.cs @@ -1,8 +1,8 @@ using System.Net.Mime; using Iceshrimp.Backend.Controllers.Attributes; -using Iceshrimp.Backend.Controllers.Renderers.ActivityPub; using Iceshrimp.Backend.Controllers.Schemas; using Iceshrimp.Backend.Core.Database; +using Iceshrimp.Backend.Core.Federation.ActivityPub; using Iceshrimp.Backend.Core.Federation.ActivityStreams; using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; using Iceshrimp.Backend.Core.Middleware; diff --git a/Iceshrimp.Backend/Controllers/Renderers/Entity/NoteRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs similarity index 87% rename from Iceshrimp.Backend/Controllers/Renderers/Entity/NoteRenderer.cs rename to Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs index 3a44ae1b..9208b865 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/Entity/NoteRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs @@ -1,7 +1,7 @@ using Iceshrimp.Backend.Controllers.Schemas; using Iceshrimp.Backend.Core.Database.Tables; -namespace Iceshrimp.Backend.Controllers.Renderers.Entity; +namespace Iceshrimp.Backend.Controllers.Renderers; public class NoteRenderer { public static NoteResponse RenderOne(Note note) { diff --git a/Iceshrimp.Backend/Controllers/Renderers/Entity/TimelineRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/TimelineRenderer.cs similarity index 83% rename from Iceshrimp.Backend/Controllers/Renderers/Entity/TimelineRenderer.cs rename to Iceshrimp.Backend/Controllers/Renderers/TimelineRenderer.cs index 05fd10fa..48bcc278 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/Entity/TimelineRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/TimelineRenderer.cs @@ -1,7 +1,7 @@ using Iceshrimp.Backend.Controllers.Schemas; using Iceshrimp.Backend.Core.Database.Tables; -namespace Iceshrimp.Backend.Controllers.Renderers.Entity; +namespace Iceshrimp.Backend.Controllers.Renderers; public class TimelineRenderer { public static TimelineResponse Render(IEnumerable notes, int limit) { diff --git a/Iceshrimp.Backend/Controllers/Renderers/Entity/UserRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/UserRenderer.cs similarity index 88% rename from Iceshrimp.Backend/Controllers/Renderers/Entity/UserRenderer.cs rename to Iceshrimp.Backend/Controllers/Renderers/UserRenderer.cs index c6d80478..bc931286 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/Entity/UserRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/UserRenderer.cs @@ -1,7 +1,7 @@ using Iceshrimp.Backend.Controllers.Schemas; using Iceshrimp.Backend.Core.Database.Tables; -namespace Iceshrimp.Backend.Controllers.Renderers.Entity; +namespace Iceshrimp.Backend.Controllers.Renderers; public class UserRenderer { public static UserResponse RenderOne(User user) { diff --git a/Iceshrimp.Backend/Controllers/UserController.cs b/Iceshrimp.Backend/Controllers/UserController.cs index cc93b036..4c1ffec0 100644 --- a/Iceshrimp.Backend/Controllers/UserController.cs +++ b/Iceshrimp.Backend/Controllers/UserController.cs @@ -1,4 +1,4 @@ -using Iceshrimp.Backend.Controllers.Renderers.Entity; +using Iceshrimp.Backend.Controllers.Renderers; using Iceshrimp.Backend.Controllers.Schemas; using Iceshrimp.Backend.Core.Database; using Microsoft.AspNetCore.Mvc; diff --git a/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs b/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs index 8bd725d6..302e6594 100644 --- a/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs +++ b/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs @@ -1,4 +1,3 @@ -using Iceshrimp.Backend.Controllers.Renderers.ActivityPub; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Federation.ActivityPub; diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs index 4b1d8339..b350a8e3 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityHandlerService.cs @@ -1,4 +1,3 @@ -using Iceshrimp.Backend.Controllers.Renderers.ActivityPub; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Federation.ActivityStreams; @@ -27,18 +26,15 @@ public class ActivityHandlerService( //TODO: validate inboxUserId switch (activity.Type) { - case "https://www.w3.org/ns/activitystreams#Create": { + case ASActivity.Types.Create: { if (activity.Object is ASNote note) return noteSvc.ProcessNote(note, activity.Actor); throw new NotImplementedException(); } - case "https://www.w3.org/ns/activitystreams#Like": { - throw new NotImplementedException(); - } - case "https://www.w3.org/ns/activitystreams#Follow": { + case ASActivity.Types.Follow: { if (activity.Object is { } obj) return Follow(obj, activity.Actor, activity.Id); throw GracefulException.UnprocessableEntity("Follow activity object is invalid"); } - case "https://www.w3.org/ns/activitystreams#Unfollow": { + case ASActivity.Types.Unfollow: { if (activity.Object is { } obj) return Unfollow(obj, activity.Actor, activity.Id); throw GracefulException.UnprocessableEntity("Unfollow activity object is invalid"); } diff --git a/Iceshrimp.Backend/Controllers/Renderers/ActivityPub/ActivityRenderer.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityRenderer.cs similarity index 93% rename from Iceshrimp.Backend/Controllers/Renderers/ActivityPub/ActivityRenderer.cs rename to Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityRenderer.cs index c5c0e268..cf5f9ace 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/ActivityPub/ActivityRenderer.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityRenderer.cs @@ -2,7 +2,7 @@ using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; using Microsoft.Extensions.Options; -namespace Iceshrimp.Backend.Controllers.Renderers.ActivityPub; +namespace Iceshrimp.Backend.Core.Federation.ActivityPub; public class ActivityRenderer(IOptions config) { public static ASActivity RenderCreate(ASObject obj, ASObject actor) { diff --git a/Iceshrimp.Backend/Controllers/Renderers/ActivityPub/NoteRenderer.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/NoteRenderer.cs similarity index 93% rename from Iceshrimp.Backend/Controllers/Renderers/ActivityPub/NoteRenderer.cs rename to Iceshrimp.Backend/Core/Federation/ActivityPub/NoteRenderer.cs index 7b4160f7..16241035 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/ActivityPub/NoteRenderer.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/NoteRenderer.cs @@ -3,7 +3,7 @@ using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; using Microsoft.Extensions.Options; -namespace Iceshrimp.Backend.Controllers.Renderers.ActivityPub; +namespace Iceshrimp.Backend.Core.Federation.ActivityPub; public class NoteRenderer(IOptions config) { public ASNote Render(Note note) { diff --git a/Iceshrimp.Backend/Controllers/Renderers/ActivityPub/UserRenderer.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/UserRenderer.cs similarity index 97% rename from Iceshrimp.Backend/Controllers/Renderers/ActivityPub/UserRenderer.cs rename to Iceshrimp.Backend/Core/Federation/ActivityPub/UserRenderer.cs index 0c0587a9..30500ae1 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/ActivityPub/UserRenderer.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/UserRenderer.cs @@ -7,7 +7,7 @@ using Iceshrimp.Backend.Core.Middleware; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -namespace Iceshrimp.Backend.Controllers.Renderers.ActivityPub; +namespace Iceshrimp.Backend.Core.Federation.ActivityPub; public class UserRenderer(IOptions config, DatabaseContext db) { public async Task Render(User user) { diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs index 902ad006..92a1ae6c 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs @@ -11,6 +11,18 @@ public class ASActivity : ASObject { [J("https://www.w3.org/ns/activitystreams#object")] [JC(typeof(ASObjectConverter))] public ASObject? Object { get; set; } + + public static class Types { + private const string Ns = "https://www.w3.org/ns/activitystreams"; + + public const string Create = $"{Ns}#Create"; + public const string Delete = $"{Ns}#Delete"; + public const string Follow = $"{Ns}#Follow"; + public const string Unfollow = $"{Ns}#Unfollow"; + public const string Accept = $"{Ns}#Accept"; + public const string Undo = $"{Ns}#Undo"; + public const string Like = $"{Ns}#Like"; + } } public sealed class ASActivityConverter : ASSerializer.ListSingleObjectConverter; \ No newline at end of file diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs index 2be73ce6..8520c37f 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs @@ -12,11 +12,7 @@ public class ASActor : ASObject { private const int SummaryLength = 2048; private static readonly List ActorTypes = [ - "https://www.w3.org/ns/activitystreams#Person", - "https://www.w3.org/ns/activitystreams#Service", - "https://www.w3.org/ns/activitystreams#Group", - "https://www.w3.org/ns/activitystreams#Organization", - "https://www.w3.org/ns/activitystreams#Application" + Types.Person, Types.Service, Types.Group, Types.Organization, Types.Application ]; [J("https://misskey-hub.net/ns#_misskey_summary")] @@ -136,6 +132,16 @@ public class ASActor : ASObject { _ => null }; } + + public static class Types { + private const string Ns = "https://www.w3.org/ns/activitystreams"; + + public const string Application = $"{Ns}#Application"; + public const string Group = $"{Ns}#Group"; + public const string Organization = $"{Ns}#Organization"; + public const string Person = $"{Ns}#Person"; + public const string Service = $"{Ns}#Service"; + } } public class ASActorConverter : ASSerializer.ListSingleObjectConverter; \ No newline at end of file diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs index ae3c1eb0..673eed82 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs @@ -53,4 +53,10 @@ public class ASNote : ASObject { return Note.NoteVisibility.Specified; } + + public static class Types { + private const string Ns = "https://www.w3.org/ns/activitystreams"; + + public const string Note = $"{Ns}#Note"; + } } \ No newline at end of file diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs index d3e9aebb..3114d496 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs @@ -15,17 +15,23 @@ public class ASObject { //FIXME: don't recurse creates and co public static ASObject? Deserialize(JToken token) { + const string ns = "https://www.w3.org/ns/activitystreams"; return token.Type switch { JTokenType.Object => token["@type"]?[0]?.Value() switch { - "https://www.w3.org/ns/activitystreams#Application" => token.ToObject(), - "https://www.w3.org/ns/activitystreams#Group" => token.ToObject(), - "https://www.w3.org/ns/activitystreams#Organization" => token.ToObject(), - "https://www.w3.org/ns/activitystreams#Person" => token.ToObject(), - "https://www.w3.org/ns/activitystreams#Service" => token.ToObject(), - "https://www.w3.org/ns/activitystreams#Note" => token.ToObject(), - "https://www.w3.org/ns/activitystreams#Create" => token.ToObject(), - "https://www.w3.org/ns/activitystreams#Follow" => token.ToObject(), - _ => token.ToObject() + ASActor.Types.Person => token.ToObject(), + ASActor.Types.Service => token.ToObject(), + ASActor.Types.Group => token.ToObject(), + ASActor.Types.Organization => token.ToObject(), + ASActor.Types.Application => token.ToObject(), + ASNote.Types.Note => token.ToObject(), + ASActivity.Types.Create => token.ToObject(), + ASActivity.Types.Delete => token.ToObject(), + ASActivity.Types.Follow => token.ToObject(), + ASActivity.Types.Unfollow => token.ToObject(), + ASActivity.Types.Accept => token.ToObject(), + ASActivity.Types.Undo => token.ToObject(), + ASActivity.Types.Like => token.ToObject(), + _ => token.ToObject() }, JTokenType.Array => Deserialize(token.First()), JTokenType.String => new ASObject { Id = token.Value() ?? "" }, diff --git a/Iceshrimp.Backend/Core/Services/NoteService.cs b/Iceshrimp.Backend/Core/Services/NoteService.cs index faf6896d..e6c6b84e 100644 --- a/Iceshrimp.Backend/Core/Services/NoteService.cs +++ b/Iceshrimp.Backend/Core/Services/NoteService.cs @@ -1,4 +1,3 @@ -using Iceshrimp.Backend.Controllers.Renderers.ActivityPub; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; diff --git a/Iceshrimp.Tests/MockObjects.cs b/Iceshrimp.Tests/MockObjects.cs index c957d66b..3f84ae50 100644 --- a/Iceshrimp.Tests/MockObjects.cs +++ b/Iceshrimp.Tests/MockObjects.cs @@ -11,7 +11,7 @@ namespace Iceshrimp.Tests; public static class MockObjects { public static readonly ASActor ASActor = new() { Id = $"https://example.org/users/{IdHelpers.GenerateSlowflakeId()}", - Type = "https://www.w3.org/ns/activitystreams#Person", + Type = ASActor.Types.Person, Url = new ASLink("https://example.org/@test"), Username = "test", DisplayName = "Test account",