From 2b141f808443af397044a1f09ef45d29cb964058 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 17 Feb 2024 16:17:39 +0100 Subject: [PATCH] [backend/federation] Enforce JSON-LD profile for activities (and make them acceptable to begin with) --- .../ActivityPub/ActivityFetcherService.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs index 26bab5ce..7b3064dd 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs @@ -1,3 +1,4 @@ +using System.Net.Http.Headers; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Federation.ActivityStreams; using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; @@ -10,6 +11,11 @@ namespace Iceshrimp.Backend.Core.Federation.ActivityPub; public class ActivityFetcherService(HttpClient client, HttpRequestService httpRqSvc, SystemUserService systemUserSvc) { + private static readonly IReadOnlyCollection AcceptableActivityTypes = + [ + "application/activity+json", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" + ]; + private static readonly JsonSerializerSettings JsonSerializerSettings = new(); //FIXME: not doing this breaks ld signatures, but doing this breaks mapping the object to datetime properties //new() { DateParseHandling = DateParseHandling.None }; @@ -22,12 +28,11 @@ public class ActivityFetcherService(HttpClient client, HttpRequestService httpRq public async Task> FetchActivityAsync(string url, User actor, UserKeypair keypair) { - var request = httpRqSvc.GetSigned(url, ["application/activity+json"], actor, keypair); + var request = httpRqSvc.GetSigned(url, AcceptableActivityTypes, actor, keypair); var response = await client.SendAsync(request); if (!response.IsSuccessStatusCode) return []; - if (response.Content.Headers.ContentType?.MediaType - is not "application/activity+json" and not "application/ld+json") + if (!IsValidActivityContentType(response.Content.Headers.ContentType)) return []; var finalUri = response.RequestMessage?.RequestUri ?? @@ -48,6 +53,17 @@ public class ActivityFetcherService(HttpClient client, HttpRequestService httpRq return activities; } + private static bool IsValidActivityContentType(MediaTypeHeaderValue? headersContentType) => + headersContentType switch + { + { MediaType: "application/activity+json" } => true, + { MediaType: "application/ld+json" } when headersContentType.Parameters.Any(p => p is + { + Name: "profile", Value: "https://www.w3.org/ns/activitystreams" + }) => true, + _ => false + }; + public async Task FetchActorAsync(string uri, User actor, UserKeypair keypair) { var activity = await FetchActivityAsync(uri, actor, keypair);