From ade4481ae95c4a2b9b6ecdbb7ffaf15d397d9189 Mon Sep 17 00:00:00 2001 From: Kopper Date: Fri, 13 Sep 2024 15:24:26 +0300 Subject: [PATCH] [backend/federation] Attempt to make id optional for some object types --- .../ActivityPub/ActivityFetcherService.cs | 4 ++-- .../ActivityStreams/Types/ASActivity.cs | 8 ++++++++ .../Federation/ActivityStreams/Types/ASActor.cs | 10 ++++++++++ .../Federation/ActivityStreams/Types/ASNote.cs | 9 +++++++++ .../Federation/ActivityStreams/Types/ASObject.cs | 16 ++++++++-------- .../ActivityStreams/Types/ASPublicKey.cs | 9 +++++++++ Iceshrimp.Backend/Core/Services/NoteService.cs | 3 ++- 7 files changed, 48 insertions(+), 11 deletions(-) diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs index adb91bb8..8e1df4cc 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs @@ -56,7 +56,7 @@ public class ActivityFetcherService( { logger.LogDebug("Fetching activity {url} as user {id}", url, actor.Id); var (activity, finalUri) = await FetchActivityInternalWrapper(url, actor, keypair); - if (activity == null) return []; + if (activity?.Id == null) return []; var activityUri = new Uri(activity.Id); @@ -70,7 +70,7 @@ public class ActivityFetcherService( logger.LogDebug("Fetching activity {url} as user {id} (attempt 2)", activityIdUri.AbsoluteUri, actor.Id); (activity, finalUri) = await FetchActivityInternalWrapper(activityIdUri.AbsoluteUri, actor, keypair); - if (activity == null) return []; + if (activity?.Id == null) return []; activityUri = new Uri(activity.Id); diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs index 71c51d97..71d3eec2 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActivity.cs @@ -10,6 +10,14 @@ namespace Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; public class ASActivity : ASObject { + [J("@id")] + [JR] + public new required string Id + { + get => base.Id ?? throw new NullReferenceException("base.Id should never be null on a required property"); + set => base.Id = value; + } + [J($"{Constants.ActivityStreamsNs}#actor")] [JC(typeof(ASActorConverter))] public ASActor? Actor { get; set; } diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs index 23637ea6..0053ef4e 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASActor.cs @@ -4,6 +4,7 @@ using Iceshrimp.Backend.Core.Extensions; using J = Newtonsoft.Json.JsonPropertyAttribute; using JC = Newtonsoft.Json.JsonConverterAttribute; using JI = Newtonsoft.Json.JsonIgnoreAttribute; +using JR = Newtonsoft.Json.JsonRequiredAttribute; using VC = Iceshrimp.Backend.Core.Federation.ActivityStreams.Types.ValueObjectConverter; namespace Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; @@ -19,6 +20,14 @@ public class ASActor : ASObject Types.Person, Types.Service, Types.Group, Types.Organization, Types.Application ]; + [J("@id")] + [JR] + public new required string Id + { + get => base.Id ?? throw new NullReferenceException("base.Id should never be null on a required property"); + set => base.Id = value; + } + [J("https://misskey-hub.net/ns#_misskey_summary")] [JC(typeof(VC))] public string? MkSummary { get; set; } @@ -173,6 +182,7 @@ public class ASActor : ASObject public static ASActor FromObject(ASObject obj) { + if (obj.Id == null) throw new Exception("Unable to convert Object to Actor: Missing or invalid id"); return new ASActor { Id = obj.Id }; } diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs index 1a07de69..a4ca52a9 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASNote.cs @@ -2,6 +2,7 @@ using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database.Tables; using J = Newtonsoft.Json.JsonPropertyAttribute; using JC = Newtonsoft.Json.JsonConverterAttribute; +using JR = Newtonsoft.Json.JsonRequiredAttribute; using JI = Newtonsoft.Json.JsonIgnoreAttribute; using VC = Iceshrimp.Backend.Core.Federation.ActivityStreams.Types.ValueObjectConverter; @@ -14,6 +15,14 @@ public class ASNote : ASObject [JI] public bool VerifiedFetch = false; public ASNote(bool withType = true) => Type = withType ? Types.Note : null; + [J("@id")] + [JR] + public new required string Id + { + get => base.Id ?? throw new NullReferenceException("base.Id should never be null on a required property"); + set => base.Id = value; + } + [J("https://misskey-hub.net/ns#_misskey_content")] [JC(typeof(VC))] public string? MkContent diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs index 994774ac..e6861564 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASObject.cs @@ -10,14 +10,6 @@ namespace Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; public class ASObject : ASObjectBase { - [J("@id")] - [JR] - public new required string Id - { - get => base.Id ?? throw new NullReferenceException("base.Id should never be null on a required property"); - set => base.Id = value; - } - [J("@type")] [JC(typeof(StringListSingleConverter))] public string? Type { get; set; } @@ -88,6 +80,14 @@ public class ASObject : ASObjectBase public class ASTombstone : ASObject { + [J("@id")] + [JR] + public new required string Id + { + get => base.Id ?? throw new NullReferenceException("base.Id should never be null on a required property"); + set => base.Id = value; + } + public ASTombstone() => Type = Types.Tombstone; } diff --git a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASPublicKey.cs b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASPublicKey.cs index 6fb7c946..ebfbc67a 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASPublicKey.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityStreams/Types/ASPublicKey.cs @@ -1,5 +1,6 @@ using Iceshrimp.Backend.Core.Configuration; using J = Newtonsoft.Json.JsonPropertyAttribute; +using JR = Newtonsoft.Json.JsonRequiredAttribute; using JC = Newtonsoft.Json.JsonConverterAttribute; using VC = Iceshrimp.Backend.Core.Federation.ActivityStreams.Types.ValueObjectConverter; @@ -7,6 +8,14 @@ namespace Iceshrimp.Backend.Core.Federation.ActivityStreams.Types; public class ASPublicKey : ASObject { + [J("@id")] + [JR] + public new required string Id + { + get => base.Id ?? throw new NullReferenceException("base.Id should never be null on a required property"); + set => base.Id = value; + } + [J($"{Constants.W3IdSecurityNs}#owner")] [JC(typeof(ASObjectBaseConverter))] public ASObjectBase? Owner { get; set; } diff --git a/Iceshrimp.Backend/Core/Services/NoteService.cs b/Iceshrimp.Backend/Core/Services/NoteService.cs index d29cfb67..64f31bc4 100644 --- a/Iceshrimp.Backend/Core/Services/NoteService.cs +++ b/Iceshrimp.Backend/Core/Services/NoteService.cs @@ -1316,7 +1316,8 @@ public class NoteService( // ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall var followingUser = await db.Users.FirstOrDefaultAsync(p => p.IsFollowing(user)); var notes = await objectResolver.IterateCollection(collection).Take(10) - .Select(p => ResolveNoteAsync(p.Id, null, followingUser, true)) + .Where(p => p.Id != null) + .Select(p => ResolveNoteAsync(p.Id!, null, followingUser, true)) .AwaitAllNoConcurrencyAsync(); var previousPins = await db.Users.Where(p => p.Id == user.Id)