From 4fc044c59573b51135b69cd130977cd734b48dfa Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sat, 6 Nov 2021 10:09:07 +0100 Subject: [PATCH] Expose group physical address to AP Signed-off-by: Thomas Citharel --- .../activity_stream/converter/actor.ex | 79 ++++++++++++------- .../activity_stream/converter/event.ex | 42 +--------- .../activity_stream/converter/utils.ex | 42 +++++++++- lib/mobilizon/actors/actor.ex | 3 +- 4 files changed, 95 insertions(+), 71 deletions(-) diff --git a/lib/federation/activity_stream/converter/actor.ex b/lib/federation/activity_stream/converter/actor.ex index 59cc713f5..8739a46e8 100644 --- a/lib/federation/activity_stream/converter/actor.ex +++ b/lib/federation/activity_stream/converter/actor.ex @@ -8,12 +8,15 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do alias Mobilizon.Actors.Actor, as: ActorModel + alias Mobilizon.Addresses.Address alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} - + alias Mobilizon.Federation.ActivityStream.Converter.Address, as: AddressConverter + alias Mobilizon.Medias.File alias Mobilizon.Service.HTTP.RemoteMediaDownloaderClient alias Mobilizon.Service.RichMedia.Parser alias Mobilizon.Web.Upload + import Mobilizon.Federation.ActivityStream.Converter.Utils, only: [get_address: 1] @behaviour Converter @@ -37,6 +40,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do banner = download_picture(get_in(data, ["image", "url"]), get_in(data, ["image", "name"]), "banner") + address = get_address(data["location"]) + %{ url: data["id"], avatar: avatar, @@ -60,7 +65,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do manually_approves_followers: data["manuallyApprovesFollowers"], type: data["type"], visibility: if(Map.get(data, "discoverable", false) == true, do: :public, else: :unlisted), - openness: data["openness"] + openness: data["openness"], + physical_address_id: if(address, do: address.id, else: nil) } end @@ -106,33 +112,11 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do } } - actor_data = - if actor.type == :Group do - Map.put(actor_data, "members", actor.members_url) - else - actor_data - end - - actor_data = - if is_nil(actor.avatar) do - actor_data - else - Map.put(actor_data, "icon", %{ - "type" => "Image", - "mediaType" => actor.avatar.content_type, - "url" => actor.avatar.url - }) - end - - if is_nil(actor.banner) do - actor_data - else - Map.put(actor_data, "image", %{ - "type" => "Image", - "mediaType" => actor.banner.content_type, - "url" => actor.banner.url - }) - end + actor_data + |> maybe_add_members(actor) + |> maybe_add_avatar_picture(actor) + |> maybe_add_banner_picture(actor) + |> maybe_add_physical_address(actor) end @spec download_picture(String.t() | nil, String.t(), String.t()) :: map() | nil @@ -146,4 +130,41 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do Map.take(file, [:content_type, :name, :url, :size]) end end + + defp maybe_add_members(actor_data, %ActorModel{type: :Group, members_url: members_url}) do + Map.put(actor_data, "members", members_url) + end + + defp maybe_add_members(actor_data, %ActorModel{}), do: actor_data + + @spec maybe_add_avatar_picture(map(), ActorModel.t()) :: map() + defp maybe_add_avatar_picture(actor_data, %ActorModel{avatar: %File{} = avatar}) do + Map.put(actor_data, "image", %{ + "type" => "Image", + "mediaType" => avatar.content_type, + "url" => avatar.url + }) + end + + defp maybe_add_avatar_picture(res, %ActorModel{avatar: _}), do: res + + @spec maybe_add_banner_picture(map(), ActorModel.t()) :: map() + defp maybe_add_banner_picture(actor_data, %ActorModel{banner: %File{} = banner}) do + Map.put(actor_data, "image", %{ + "type" => "Image", + "mediaType" => banner.content_type, + "url" => banner.url + }) + end + + defp maybe_add_banner_picture(res, %ActorModel{banner: _}), do: res + + @spec maybe_add_physical_address(map(), ActorModel.t()) :: map() + defp maybe_add_physical_address(res, %ActorModel{ + physical_address: %Address{} = physical_address + }) do + Map.put(res, "location", AddressConverter.model_to_as(physical_address)) + end + + defp maybe_add_physical_address(res, %ActorModel{physical_address: _}), do: res end diff --git a/lib/federation/activity_stream/converter/event.ex b/lib/federation/activity_stream/converter/event.ex index 78d6ccb55..2d5fa9ff4 100644 --- a/lib/federation/activity_stream/converter/event.ex +++ b/lib/federation/activity_stream/converter/event.ex @@ -7,7 +7,6 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do """ alias Mobilizon.Actors.Actor - alias Mobilizon.Addresses alias Mobilizon.Addresses.Address alias Mobilizon.Events.Event, as: EventModel alias Mobilizon.Medias.Media @@ -25,7 +24,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do fetch_mentions: 1, build_tags: 1, maybe_fetch_actor_and_attributed_to_id: 1, - process_pictures: 2 + process_pictures: 2, + get_address: 1 ] require Logger @@ -192,44 +192,6 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do defp get_metdata(_), do: [] - @spec get_address(map | binary | nil) :: Address.t() | nil - defp get_address(address_url) when is_binary(address_url) do - get_address(%{"id" => address_url}) - end - - defp get_address(%{"id" => url} = map) when is_map(map) and is_binary(url) do - Logger.debug("Address with an URL, let's check against our own database") - - case Addresses.get_address_by_url(url) do - %Address{} = address -> - address - - _ -> - Logger.debug("not in our database, let's try to create it") - map = Map.put(map, "url", map["id"]) - do_get_address(map) - end - end - - defp get_address(map) when is_map(map) do - do_get_address(map) - end - - defp get_address(nil), do: nil - - @spec do_get_address(map) :: Address.t() | nil - defp do_get_address(map) do - map = AddressConverter.as_to_model_data(map) - - case Addresses.create_address(map) do - {:ok, %Address{} = address} -> - address - - _ -> - nil - end - end - defp get_visibility(object), do: if(@ap_public in object["to"], do: :public, else: :unlisted) @spec date_to_string(DateTime.t() | nil) :: String.t() diff --git a/lib/federation/activity_stream/converter/utils.ex b/lib/federation/activity_stream/converter/utils.ex index b05eb6d30..ebc572c2e 100644 --- a/lib/federation/activity_stream/converter/utils.ex +++ b/lib/federation/activity_stream/converter/utils.ex @@ -3,14 +3,16 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do Various utils for converters. """ - alias Mobilizon.{Actors, Events} + alias Mobilizon.{Actors, Addresses, Events} alias Mobilizon.Actors.Actor + alias Mobilizon.Addresses.Address alias Mobilizon.Events.Tag alias Mobilizon.Medias.Media alias Mobilizon.Mention alias Mobilizon.Storage.Repo alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor + alias Mobilizon.Federation.ActivityStream.Converter.Address, as: AddressConverter alias Mobilizon.Federation.ActivityStream.Converter.Media, as: MediaConverter alias Mobilizon.Web.Endpoint @@ -252,4 +254,42 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do defp get_banner_picture(attachments) do Enum.find(attachments, &(&1["type"] == "Document" && &1["name"] == @banner_picture_name)) end + + @spec get_address(map | binary | nil) :: Address.t() | nil + def get_address(address_url) when is_binary(address_url) do + get_address(%{"id" => address_url}) + end + + def get_address(%{"id" => url} = map) when is_map(map) and is_binary(url) do + Logger.debug("Address with an URL, let's check against our own database") + + case Addresses.get_address_by_url(url) do + %Address{} = address -> + address + + _ -> + Logger.debug("not in our database, let's try to create it") + map = Map.put(map, "url", map["id"]) + do_get_address(map) + end + end + + def get_address(map) when is_map(map) do + do_get_address(map) + end + + def get_address(nil), do: nil + + @spec do_get_address(map) :: Address.t() | nil + defp do_get_address(map) do + map = AddressConverter.as_to_model_data(map) + + case Addresses.create_address(map) do + {:ok, %Address{} = address} -> + address + + _ -> + nil + end + end end diff --git a/lib/mobilizon/actors/actor.ex b/lib/mobilizon/actors/actor.ex index 205d52b45..47f9bc066 100644 --- a/lib/mobilizon/actors/actor.ex +++ b/lib/mobilizon/actors/actor.ex @@ -124,7 +124,8 @@ defmodule Mobilizon.Actors.Actor do :summary, :manually_approves_followers, :visibility, - :openness + :openness, + :physical_address_id ] @remote_actor_creation_attrs @remote_actor_creation_required_attrs ++ @remote_actor_creation_optional_attrs