Allow for attachment to be a single object in user data #783

Merged
floatingghost merged 2 commits from single-attachment into develop 2024-05-27 01:44:54 +00:00
3 changed files with 81 additions and 0 deletions
Showing only changes of commit da67e69af5 - Show all commits

View file

@ -1545,10 +1545,15 @@ defp normalize_also_known_as(aka) when is_list(aka), do: aka
defp normalize_also_known_as(aka) when is_binary(aka), do: [aka]
defp normalize_also_known_as(nil), do: []
defp normalize_attachment(%{} = attachment), do: [attachment]
defp normalize_attachment(attachment) when is_list(attachment), do: attachment
defp normalize_attachment(_), do: []
defp object_to_user_data(data, additional) do
fields =
data
|> Map.get("attachment", [])
|> normalize_attachment()
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)

Just a though feel free to dismiss: in case an attachment list contains external objects minified to just their ID or something else entirely, it might be good to also change the filter to:

fn
  %{"type" => t} -> t == "PropertyValue"
  _ -> false
end

Then we’d only discard unsupported attachments rather than rejecting the entire actor. On the downside, dropped entries might take longer to spot increasing the time until a federation issue gets fixed; not sure how relevant though

Just a though feel free to dismiss: in case an attachment list contains external objects minified to just their ID or something else entirely, it might be good to also change the filter to: ```elixir fn %{"type" => t} -> t == "PropertyValue" _ -> false end ``` Then we’d only discard unsupported attachments rather than rejecting the entire actor. On the downside, dropped entries might take longer to spot increasing the time until a federation issue gets fixed; not sure how relevant though
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)

View file

@ -0,0 +1,53 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"blurhash": "toot:blurhash",
"Emoji": "toot:Emoji",
"focalPoint": {
"@container": "@list",
"@id": "toot:focalPoint"
},
"Hashtag": "as:Hashtag",
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"sensitive": "as:sensitive",
"toot": "http://joinmastodon.org/ns#",
"votersCount": "toot:votersCount",
"featured": {
"@id": "toot:featured",
"@type": "@id"
}
},
"https://w3id.org/security/v1"
],
"id": "https://fedi.vision/@vote@fedi.vision/",
"type": "Person",
"toot:discoverable": true,
"inbox": "https://fedi.vision/@vote@fedi.vision/inbox/",
"publicKey": {
"id": "https://fedi.vision/@vote@fedi.vision/#main-key",
"owner": "https://fedi.vision/@vote@fedi.vision/",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj2f+uQtdoBO9X/u2Qso4\nxHYdfy8zB24m9Gg982/ts88DAMLxZUzX0JsBWT7coL0Ipf4NSbVaqS6nKrr2P8Qs\nf97wMhowyuYxK22BMPcbpfZkFj3tVT/JkDx2iujBJJ5ZBO5KRlupjDTqV4rOAY7F\n58ad0jK9PsJNJMsJ/b8+0t3Q/K+RqCGVmtK+iPSigOYoiKoquyRzHLTfP+mpOlDa\n3f+uyAbFya7CpcgBx1zz0PALWA+oh/zhZK4yT6719Esa8SDcoJ0ws70zMxWekq1A\n3ia88/Io6SY2qFNBpzzXGO3JK8OFRFtmPV8ZfAh5Pv6y52iuTJ21kxjAG7ZTP/fY\nBQIDAQAB\n-----END PUBLIC KEY-----\n"
},
"attachment": {
"type": "PropertyValue",
"value": "<a href=\"https://fedivision.party/vote\" rel=\"nofollow\"><span class=\"invisible\">https://</span>fedivision.party/vote</a>",
"name": "More details"
},
"endpoints": {
"sharedInbox": "https://fedi.vision/inbox/"
},
"followers": "https://fedi.vision/@vote@fedi.vision/followers/",
"following": "https://fedi.vision/@vote@fedi.vision/following/",
"icon": {
"type": "Image",
"mediaType": "image/webp",
"url": "https://eu-central-1.linodeobjects.com:443/st4/profile_images/2024/5/9/RwqTbeYx16gauXPXvt-CaysOnGw.webp"
},
"name": "FediVision Vote Bot",
"outbox": "https://fedi.vision/@vote@fedi.vision/outbox/",
"preferredUsername": "vote",
"published": "2024-05-09T09:04:04Z",
"summary": "<p>New in 2024, this is the bot that will count your #Fedivision vote! Accept no substitutes!</p><p>Send this account a toot in the form<br> vote ABCD EFGH IJKL<br>substituting the (up to) three codes for the songs you want to win. Punctuation ignored, case insensitive, order is unimportant. Only your latest toot counts, so change your vote with a new toot.</p>",
"url": "https://fedi.vision/@vote/"
}

View file

@ -233,6 +233,29 @@ test "works for bridgy actors" do
}
end
test "works for takahe actors" do
user_id = "https://fedi.vision/@vote@fedi.vision/"
Tesla.Mock.mock(fn
%{method: :get, url: ^user_id} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/users_mock/takahe_user.json"),
headers: [{"content-type", "application/activity+json"}]
}
end)
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
assert user.actor_type == "Person"
assert [
%{
"name" => "More details"
}
] = user.fields
end
test "fetches user featured collection" do
ap_id = "https://example.com/users/lain"