Add addressable lists
This commit is contained in:
parent
8c9227c1f1
commit
a3dc02d282
|
@ -28,19 +28,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
# For Announce activities, we filter the recipients based on following status for any actors
|
||||
# that match actual users. See issue #164 for more information about why this is necessary.
|
||||
defp get_recipients(%{"type" => "Announce"} = data) do
|
||||
to = data["to"] || []
|
||||
cc = data["cc"] || []
|
||||
to = Map.get(data, "to", [])
|
||||
cc = Map.get(data, "cc", [])
|
||||
bcc = Map.get(data, "bcc", [])
|
||||
actor = User.get_cached_by_ap_id(data["actor"])
|
||||
|
||||
recipients =
|
||||
(to ++ cc)
|
||||
|> Enum.filter(fn recipient ->
|
||||
Enum.filter(Enum.concat([to, cc, bcc]), fn recipient ->
|
||||
case User.get_cached_by_ap_id(recipient) do
|
||||
nil ->
|
||||
true
|
||||
|
||||
user ->
|
||||
User.following?(user, actor)
|
||||
nil -> true
|
||||
user -> User.following?(user, actor)
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -48,17 +45,19 @@ defp get_recipients(%{"type" => "Announce"} = data) do
|
|||
end
|
||||
|
||||
defp get_recipients(%{"type" => "Create"} = data) do
|
||||
to = data["to"] || []
|
||||
cc = data["cc"] || []
|
||||
actor = data["actor"] || []
|
||||
recipients = (to ++ cc ++ [actor]) |> Enum.uniq()
|
||||
to = Map.get(data, "to", [])
|
||||
cc = Map.get(data, "cc", [])
|
||||
bcc = Map.get(data, "bcc", [])
|
||||
actor = Map.get(data, "actor", [])
|
||||
recipients = [to, cc, bcc, [actor]] |> Enum.concat() |> Enum.uniq()
|
||||
{recipients, to, cc}
|
||||
end
|
||||
|
||||
defp get_recipients(data) do
|
||||
to = data["to"] || []
|
||||
cc = data["cc"] || []
|
||||
recipients = to ++ cc
|
||||
to = Map.get(data, "to", [])
|
||||
cc = Map.get(data, "cc", [])
|
||||
bcc = Map.get(data, "bcc", [])
|
||||
recipients = Enum.concat([to, cc, bcc])
|
||||
{recipients, to, cc}
|
||||
end
|
||||
|
||||
|
@ -917,22 +916,55 @@ def should_federate?(inbox, public) do
|
|||
end
|
||||
end
|
||||
|
||||
def publish(actor, activity) do
|
||||
remote_followers =
|
||||
defp recipients(actor, activity) do
|
||||
Pleroma.Web.Salmon.remote_users(activity) ++
|
||||
if actor.follower_address in activity.recipients do
|
||||
{:ok, followers} = User.get_followers(actor)
|
||||
followers |> Enum.filter(&(!&1.local))
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def publish(actor, %{data: %{"bcc" => bcc}} = activity) when is_list(bcc) and bcc != [] do
|
||||
public = is_public?(activity)
|
||||
|
||||
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
recipients = recipients(actor, activity)
|
||||
|
||||
recipients
|
||||
|> Enum.filter(&User.ap_enabled?/1)
|
||||
|> Enum.map(fn %{info: %{source_data: data}} -> data["inbox"] end)
|
||||
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
||||
|> Instances.filter_reachable()
|
||||
|> Enum.each(fn {inbox, unreachable_since} ->
|
||||
%User{ap_id: cc} =
|
||||
Enum.find(recipients, fn %{info: %{source_data: data}} -> data["inbox"] == inbox end)
|
||||
|
||||
json =
|
||||
data
|
||||
|> Map.put("cc", [cc])
|
||||
|> Map.put("directMessage", true)
|
||||
|> Jason.encode!()
|
||||
|
||||
Federator.publish_single_ap(%{
|
||||
inbox: inbox,
|
||||
json: json,
|
||||
actor: actor,
|
||||
id: activity.data["id"],
|
||||
unreachable_since: unreachable_since
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
def publish(actor, activity) do
|
||||
public = is_public?(activity)
|
||||
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
json = Jason.encode!(data)
|
||||
|
||||
(Pleroma.Web.Salmon.remote_users(activity) ++ remote_followers)
|
||||
|> Enum.filter(fn user -> User.ap_enabled?(user) end)
|
||||
recipients(actor, activity)
|
||||
|> Enum.filter(&User.ap_enabled?/1)
|
||||
|> Enum.map(fn %{info: %{source_data: data}} ->
|
||||
(is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"]
|
||||
end)
|
||||
|
|
|
@ -741,13 +741,16 @@ def prepare_object(object) do
|
|||
|
||||
def prepare_outgoing(%{"type" => "Create", "object" => object_id} = data) do
|
||||
object =
|
||||
Object.normalize(object_id).data
|
||||
object_id
|
||||
|> Object.normalize()
|
||||
|> Map.get(:data)
|
||||
|> prepare_object
|
||||
|
||||
data =
|
||||
data
|
||||
|> Map.put("object", object)
|
||||
|> Map.merge(Utils.make_json_ld_header())
|
||||
|> Map.delete("bcc")
|
||||
|
||||
{:ok, data}
|
||||
end
|
||||
|
|
|
@ -119,6 +119,10 @@ def get_visibility(%{"visibility" => visibility})
|
|||
when visibility in ~w{public unlisted private direct},
|
||||
do: visibility
|
||||
|
||||
def get_visibility(%{"visibility" => "list:" <> list_id}) do
|
||||
{:list, String.to_integer(list_id)}
|
||||
end
|
||||
|
||||
def get_visibility(%{"in_reply_to_status_id" => status_id}) when not is_nil(status_id) do
|
||||
case get_replied_to_activity(status_id) do
|
||||
nil ->
|
||||
|
@ -149,6 +153,7 @@ def post(user, %{"status" => status} = data) do
|
|||
visibility
|
||||
),
|
||||
{to, cc} <- to_for_user_and_mentions(user, mentions, in_reply_to, visibility),
|
||||
{:ok, bcc} <- bcc_for_list(user, visibility),
|
||||
context <- make_context(in_reply_to),
|
||||
cw <- data["spoiler_text"],
|
||||
full_payload <- String.trim(status <> (data["spoiler_text"] || "")),
|
||||
|
@ -174,19 +179,16 @@ def post(user, %{"status" => status} = data) do
|
|||
Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url()}#{file}")
|
||||
end)
|
||||
) do
|
||||
res =
|
||||
ActivityPub.create(
|
||||
%{
|
||||
to: to,
|
||||
actor: user,
|
||||
context: context,
|
||||
object: object,
|
||||
additional: %{"cc" => cc, "directMessage" => visibility == "direct"}
|
||||
additional: %{"cc" => cc, "bcc" => bcc, "directMessage" => visibility == "direct"}
|
||||
},
|
||||
Pleroma.Web.ControllerHelper.truthy_param?(data["preview"]) || false
|
||||
)
|
||||
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
|||
alias Pleroma.Activity
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Formatter
|
||||
alias Pleroma.List
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
|
@ -102,6 +103,20 @@ def to_for_user_and_mentions(_user, mentions, inReplyTo, "direct") do
|
|||
end
|
||||
end
|
||||
|
||||
def to_for_user_and_mentions(_user, _mentions, _inReplyTo, _), do: {[], []}
|
||||
|
||||
def bcc_for_list(user, {:list, list_id}) do
|
||||
with {_, %List{} = list} <- {:list, List.get(list_id, user)},
|
||||
{:ok, following} <- List.get_following(list) do
|
||||
{:ok, Enum.map(following, & &1.ap_id)}
|
||||
else
|
||||
{:list, _} -> {:error, "List not found"}
|
||||
err -> err
|
||||
end
|
||||
end
|
||||
|
||||
def bcc_for_list(_, _), do: {:ok, []}
|
||||
|
||||
def make_content_html(
|
||||
status,
|
||||
attachments,
|
||||
|
|
|
@ -157,10 +157,12 @@ def encode(private_key, doc) do
|
|||
end
|
||||
|
||||
def remote_users(%{data: %{"to" => to} = data}) do
|
||||
to = to ++ (data["cc"] || [])
|
||||
cc = Map.get(data, "cc", [])
|
||||
bcc = Map.get(data, "bcc", [])
|
||||
|
||||
to
|
||||
|> Enum.map(fn id -> User.get_cached_by_ap_id(id) end)
|
||||
[to, cc, bcc]
|
||||
|> Enum.concat()
|
||||
|> Enum.map(&User.get_cached_by_ap_id/1)
|
||||
|> Enum.filter(fn user -> user && !user.local end)
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue