Expose group physical address to AP

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-11-06 10:09:07 +01:00
parent 096c3a435a
commit 4fc044c595
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
4 changed files with 95 additions and 71 deletions

View file

@ -8,12 +8,15 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
alias Mobilizon.Actors.Actor, as: ActorModel alias Mobilizon.Actors.Actor, as: ActorModel
alias Mobilizon.Addresses.Address
alias Mobilizon.Federation.ActivityPub.Utils alias Mobilizon.Federation.ActivityPub.Utils
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible} 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.HTTP.RemoteMediaDownloaderClient
alias Mobilizon.Service.RichMedia.Parser alias Mobilizon.Service.RichMedia.Parser
alias Mobilizon.Web.Upload alias Mobilizon.Web.Upload
import Mobilizon.Federation.ActivityStream.Converter.Utils, only: [get_address: 1]
@behaviour Converter @behaviour Converter
@ -37,6 +40,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
banner = banner =
download_picture(get_in(data, ["image", "url"]), get_in(data, ["image", "name"]), "banner") download_picture(get_in(data, ["image", "url"]), get_in(data, ["image", "name"]), "banner")
address = get_address(data["location"])
%{ %{
url: data["id"], url: data["id"],
avatar: avatar, avatar: avatar,
@ -60,7 +65,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
manually_approves_followers: data["manuallyApprovesFollowers"], manually_approves_followers: data["manuallyApprovesFollowers"],
type: data["type"], type: data["type"],
visibility: if(Map.get(data, "discoverable", false) == true, do: :public, else: :unlisted), 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 end
@ -106,33 +112,11 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
} }
} }
actor_data = actor_data
if actor.type == :Group do |> maybe_add_members(actor)
Map.put(actor_data, "members", actor.members_url) |> maybe_add_avatar_picture(actor)
else |> maybe_add_banner_picture(actor)
actor_data |> maybe_add_physical_address(actor)
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
end end
@spec download_picture(String.t() | nil, String.t(), String.t()) :: map() | nil @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]) Map.take(file, [:content_type, :name, :url, :size])
end end
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 end

View file

@ -7,7 +7,6 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
""" """
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Addresses
alias Mobilizon.Addresses.Address alias Mobilizon.Addresses.Address
alias Mobilizon.Events.Event, as: EventModel alias Mobilizon.Events.Event, as: EventModel
alias Mobilizon.Medias.Media alias Mobilizon.Medias.Media
@ -25,7 +24,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
fetch_mentions: 1, fetch_mentions: 1,
build_tags: 1, build_tags: 1,
maybe_fetch_actor_and_attributed_to_id: 1, maybe_fetch_actor_and_attributed_to_id: 1,
process_pictures: 2 process_pictures: 2,
get_address: 1
] ]
require Logger require Logger
@ -192,44 +192,6 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
defp get_metdata(_), 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) defp get_visibility(object), do: if(@ap_public in object["to"], do: :public, else: :unlisted)
@spec date_to_string(DateTime.t() | nil) :: String.t() @spec date_to_string(DateTime.t() | nil) :: String.t()

View file

@ -3,14 +3,16 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
Various utils for converters. Various utils for converters.
""" """
alias Mobilizon.{Actors, Events} alias Mobilizon.{Actors, Addresses, Events}
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Addresses.Address
alias Mobilizon.Events.Tag alias Mobilizon.Events.Tag
alias Mobilizon.Medias.Media alias Mobilizon.Medias.Media
alias Mobilizon.Mention alias Mobilizon.Mention
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor 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.Federation.ActivityStream.Converter.Media, as: MediaConverter
alias Mobilizon.Web.Endpoint alias Mobilizon.Web.Endpoint
@ -252,4 +254,42 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
defp get_banner_picture(attachments) do defp get_banner_picture(attachments) do
Enum.find(attachments, &(&1["type"] == "Document" && &1["name"] == @banner_picture_name)) Enum.find(attachments, &(&1["type"] == "Document" && &1["name"] == @banner_picture_name))
end 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 end

View file

@ -124,7 +124,8 @@ defmodule Mobilizon.Actors.Actor do
:summary, :summary,
:manually_approves_followers, :manually_approves_followers,
:visibility, :visibility,
:openness :openness,
:physical_address_id
] ]
@remote_actor_creation_attrs @remote_actor_creation_required_attrs ++ @remote_actor_creation_attrs @remote_actor_creation_required_attrs ++
@remote_actor_creation_optional_attrs @remote_actor_creation_optional_attrs