[backend/federation] Fix handling of incorrectly namespaced @value type ASCollections (ISH-67)

This commit is contained in:
Laura Hausmann 2024-03-01 03:20:27 +01:00
parent 2d92d27dbf
commit 38a67b17fe
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
7 changed files with 175 additions and 8 deletions

View file

@ -4,6 +4,9 @@
"@id": "https://www.w3.org/ns/activitystreams#movedTo",
"@type": "@id"
},
"featured": "http://joinmastodon.org/ns#featured"
"featured": {
"@id": "http://joinmastodon.org/ns#featured",
"@type": "@id"
}
}
}

View file

@ -98,7 +98,7 @@ public class ASActor : ASObject
public List<ASLink>? AlsoKnownAs { get; set; }
[J("http://joinmastodon.org/ns#featured")]
[JC(typeof(VC))]
[JC(typeof(ASOrderedCollectionConverter))]
public ASOrderedCollection? Featured { get; set; }
[J("http://joinmastodon.org/ns#featuredTags")]

View file

@ -40,7 +40,45 @@ public class ASCollection : ASObject
public const string ObjectType = $"{Constants.ActivityStreamsNs}#Collection";
}
public sealed class ASCollectionConverter : ASSerializer.ListSingleObjectConverter<ASCollection>;
public sealed class ASCollectionConverter : JsonConverter
{
public override bool CanWrite => false;
public override bool CanConvert(Type objectType)
{
return true;
}
public override object? ReadJson(
JsonReader reader, Type objectType, object? existingValue,
JsonSerializer serializer
)
{
if (reader.TokenType == JsonToken.StartArray)
{
var obj = JArray.Load(reader);
var valueList = obj.ToObject<List<LDValueObject<object?>>>();
if (valueList is { Count: > 0 })
return VC.HandleObject(valueList[0], objectType);
var list = obj.ToObject<List<ASCollection?>>();
return list == null || list.Count == 0 ? null : list[0];
}
if (reader.TokenType == JsonToken.StartObject)
{
var obj = JObject.Load(reader);
var valueObj = obj.ToObject<LDValueObject<object?>>();
return valueObj != null ? VC.HandleObject(valueObj, objectType) : obj.ToObject<ASCollection?>();
}
return null;
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
internal sealed class ASCollectionItemsConverter : JsonConverter
{

View file

@ -1,5 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Iceshrimp.Backend.Core.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using J = Newtonsoft.Json.JsonPropertyAttribute;
using JC = Newtonsoft.Json.JsonConverterAttribute;
using VC = Iceshrimp.Backend.Core.Federation.ActivityStreams.Types.ValueObjectConverter;
@ -36,4 +38,44 @@ public class ASCollectionPage : ASObject
public const string ObjectType = $"{Constants.ActivityStreamsNs}#CollectionPage";
}
public sealed class ASCollectionPageConverter : ASSerializer.ListSingleObjectConverter<ASCollectionPage>;
public sealed class ASCollectionPageConverter : JsonConverter
{
public override bool CanWrite => false;
public override bool CanConvert(Type objectType)
{
return true;
}
public override object? ReadJson(
JsonReader reader, Type objectType, object? existingValue,
JsonSerializer serializer
)
{
if (reader.TokenType == JsonToken.StartArray)
{
var obj = JArray.Load(reader);
var valueList = obj.ToObject<List<LDValueObject<object?>>>();
if (valueList is { Count: > 0 })
return VC.HandleObject(valueList[0], objectType);
var list = obj.ToObject<List<ASCollectionPage?>>();
return list == null || list.Count == 0 ? null : list[0];
}
if (reader.TokenType == JsonToken.StartObject)
{
var obj = JObject.Load(reader);
var valueObj = obj.ToObject<LDValueObject<object?>>();
return valueObj != null
? VC.HandleObject(valueObj, objectType)
: obj.ToObject<ASCollectionPage?>();
}
return null;
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

View file

@ -1,5 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Iceshrimp.Backend.Core.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using J = Newtonsoft.Json.JsonPropertyAttribute;
using JC = Newtonsoft.Json.JsonConverterAttribute;
using JI = Newtonsoft.Json.JsonIgnoreAttribute;
@ -25,4 +27,44 @@ public class ASOrderedCollection : ASCollection
public new const string ObjectType = $"{Constants.ActivityStreamsNs}#OrderedCollection";
}
public sealed class ASOrderedCollectionConverter : ASSerializer.ListSingleObjectConverter<ASOrderedCollection>;
public sealed class ASOrderedCollectionConverter : JsonConverter
{
public override bool CanWrite => false;
public override bool CanConvert(Type objectType)
{
return true;
}
public override object? ReadJson(
JsonReader reader, Type objectType, object? existingValue,
JsonSerializer serializer
)
{
if (reader.TokenType == JsonToken.StartArray)
{
var obj = JArray.Load(reader);
var valueList = obj.ToObject<List<LDValueObject<object?>>>();
if (valueList?.Any(p => p.Value != null) ?? false)
return ValueObjectConverter.HandleObject(valueList[0], objectType);
var list = obj.ToObject<List<ASOrderedCollection?>>();
return list == null || list.Count == 0 ? null : list[0];
}
if (reader.TokenType == JsonToken.StartObject)
{
var obj = JObject.Load(reader);
var valueObj = obj.ToObject<LDValueObject<object?>>();
return valueObj is { Value: not null }
? ValueObjectConverter.HandleObject(valueObj, objectType)
: obj.ToObject<ASOrderedCollection?>();
}
return null;
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

View file

@ -1,5 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Iceshrimp.Backend.Core.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using J = Newtonsoft.Json.JsonPropertyAttribute;
using JC = Newtonsoft.Json.JsonConverterAttribute;
using VC = Iceshrimp.Backend.Core.Federation.ActivityStreams.Types.ValueObjectConverter;
@ -36,4 +38,44 @@ public class ASOrderedCollectionPage : ASObject
public const string ObjectType = $"{Constants.ActivityStreamsNs}#OrderedCollectionPage";
}
public sealed class ASOrderedCollectionPageConverter : ASSerializer.ListSingleObjectConverter<ASOrderedCollectionPage>;
public sealed class ASOrderedCollectionPageConverter : JsonConverter
{
public override bool CanWrite => false;
public override bool CanConvert(Type objectType)
{
return true;
}
public override object? ReadJson(
JsonReader reader, Type objectType, object? existingValue,
JsonSerializer serializer
)
{
if (reader.TokenType == JsonToken.StartArray)
{
var obj = JArray.Load(reader);
var valueList = obj.ToObject<List<LDValueObject<object?>>>();
if (valueList is { Count: > 0 })
return VC.HandleObject(valueList[0], objectType);
var list = obj.ToObject<List<ASOrderedCollectionPage?>>();
return list == null || list.Count == 0 ? null : list[0];
}
if (reader.TokenType == JsonToken.StartObject)
{
var obj = JObject.Load(reader);
var valueObj = obj.ToObject<LDValueObject<object?>>();
return valueObj != null
? VC.HandleObject(valueObj, objectType)
: obj.ToObject<ASOrderedCollectionPage?>();
}
return null;
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

View file

@ -45,7 +45,7 @@ public class ValueObjectConverter : JsonConverter
return null;
}
private static object? HandleObject(LDValueObject<object?>? obj, Type objectType)
internal static object? HandleObject(LDValueObject<object?>? obj, Type objectType)
{
if (obj?.Value is string s && (objectType == typeof(DateTime?) || objectType == typeof(DateTime)))
{