Fix incoming Accept activities from participations we don't already have
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
4c9065ce68
commit
c56b898379
|
@ -850,8 +850,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
# Handle incoming `Accept` activities wrapping a `Join` activity on an event
|
# Handle incoming `Accept` activities wrapping a `Join` activity on an event
|
||||||
defp do_handle_incoming_accept_join(join_object, %Actor{} = actor_accepting) do
|
defp do_handle_incoming_accept_join(join_object, %Actor{} = actor_accepting) do
|
||||||
case get_participant(join_object, actor_accepting) do
|
case get_participant(join_object, actor_accepting) do
|
||||||
{:ok, participant} ->
|
{:ok, activity, participant} ->
|
||||||
do_handle_incoming_accept_join_event(participant, actor_accepting)
|
do_handle_incoming_accept_join_event(participant, actor_accepting, activity)
|
||||||
|
|
||||||
{:error, _err} ->
|
{:error, _err} ->
|
||||||
case get_member(join_object) do
|
case get_member(join_object) do
|
||||||
|
@ -870,17 +870,22 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_handle_incoming_accept_join_event(%Participant{role: :participant}, _actor) do
|
defp do_handle_incoming_accept_join_event(
|
||||||
|
%Participant{role: :participant} = participant,
|
||||||
|
_actor,
|
||||||
|
activity
|
||||||
|
) do
|
||||||
Logger.debug(
|
Logger.debug(
|
||||||
"Tried to handle an Accept activity on a Join activity with a event object but the participant is already validated"
|
"Tried to handle an Accept activity on a Join activity with a event object but the participant is already validated"
|
||||||
)
|
)
|
||||||
|
|
||||||
nil
|
{:ok, activity, participant}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_handle_incoming_accept_join_event(
|
defp do_handle_incoming_accept_join_event(
|
||||||
%Participant{role: role, event: event} = participant,
|
%Participant{role: role, event: event} = participant,
|
||||||
%Actor{} = actor_accepting
|
%Actor{} = actor_accepting,
|
||||||
|
_activity
|
||||||
)
|
)
|
||||||
when role in [:not_approved, :rejected] do
|
when role in [:not_approved, :rejected] do
|
||||||
with %Event{} = event <- Events.get_event_with_preload!(event.id),
|
with %Event{} = event <- Events.get_event_with_preload!(event.id),
|
||||||
|
@ -932,7 +937,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
|
|
||||||
# Handle incoming `Reject` activities wrapping a `Join` activity on an event
|
# Handle incoming `Reject` activities wrapping a `Join` activity on an event
|
||||||
defp do_handle_incoming_reject_join(join_object, %Actor{} = actor_accepting) do
|
defp do_handle_incoming_reject_join(join_object, %Actor{} = actor_accepting) do
|
||||||
with {:join_event, {:ok, %Participant{event: event, role: role} = participant}}
|
with {:join_event, {:ok, _activity, %Participant{event: event, role: role} = participant}}
|
||||||
when role != :rejected <-
|
when role != :rejected <-
|
||||||
{:join_event, get_participant(join_object, actor_accepting)},
|
{:join_event, get_participant(join_object, actor_accepting)},
|
||||||
{:event, %Event{} = event} <- {:event, Events.get_event_with_preload!(event.id)},
|
{:event, %Event{} = event} <- {:event, Events.get_event_with_preload!(event.id)},
|
||||||
|
@ -943,7 +948,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
:ok <- Participation.send_emails_to_local_user(participant) do
|
:ok <- Participation.send_emails_to_local_user(participant) do
|
||||||
{:ok, activity, participant}
|
{:ok, activity, participant}
|
||||||
else
|
else
|
||||||
{:join_event, {:ok, %Participant{role: :rejected}}} ->
|
{:join_event, {:ok, _activity, %Participant{role: :rejected}}} ->
|
||||||
Logger.warn(
|
Logger.warn(
|
||||||
"Tried to handle an Reject activity on a Join activity with a event object but the participant is already rejected"
|
"Tried to handle an Reject activity on a Join activity with a event object but the participant is already rejected"
|
||||||
)
|
)
|
||||||
|
@ -1040,18 +1045,18 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_participant(join_object, %Actor{} = actor_accepting, loop \\ 1) do
|
defp get_participant(join_object, %Actor{} = actor_accepting, loop \\ 1, activity \\ nil) do
|
||||||
with join_object_id when not is_nil(join_object_id) <- Utils.get_url(join_object),
|
with join_object_id when not is_nil(join_object_id) <- Utils.get_url(join_object),
|
||||||
{:not_found, %Participant{} = participant} <-
|
{:not_found, %Participant{} = participant} <-
|
||||||
{:not_found, Events.get_participant_by_url(join_object_id)} do
|
{:not_found, Events.get_participant_by_url(join_object_id)} do
|
||||||
{:ok, participant}
|
{:ok, activity, participant}
|
||||||
else
|
else
|
||||||
{:not_found, _err} ->
|
{:not_found, _err} ->
|
||||||
with true <- is_map(join_object),
|
with true <- is_map(join_object),
|
||||||
true <- loop < 2,
|
true <- loop < 2,
|
||||||
true <- Utils.are_same_origin?(actor_accepting.url, join_object["id"]),
|
true <- Utils.are_same_origin?(actor_accepting.url, join_object["id"]),
|
||||||
{:ok, _activity, %Participant{url: participant_url}} <- handle_incoming(join_object) do
|
{:ok, activity, %Participant{url: participant_url}} <- handle_incoming(join_object) do
|
||||||
get_participant(participant_url, actor_accepting, 2)
|
get_participant(participant_url, actor_accepting, 2, activity)
|
||||||
else
|
else
|
||||||
_ ->
|
_ ->
|
||||||
{:error, "Participant URL not found"}
|
{:error, "Participant URL not found"}
|
||||||
|
|
73
test/federation/activity_pub/transmogrifier/accept_test.exs
Normal file
73
test/federation/activity_pub/transmogrifier/accept_test.exs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.AcceptTest do
|
||||||
|
use Mobilizon.DataCase
|
||||||
|
|
||||||
|
import Mox
|
||||||
|
alias Mobilizon.Federation.ActivityPub.Transmogrifier
|
||||||
|
alias Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||||
|
|
||||||
|
describe "Receiving an Accept Join Event activity from a foreign instance" do
|
||||||
|
@base_actor_data File.read!("test/fixtures/mastodon-actor.json")
|
||||||
|
|> Jason.decode!()
|
||||||
|
@actor_url "https://mobilizon.extinctionrebellion.fr/@anonymous"
|
||||||
|
@actor_data @base_actor_data
|
||||||
|
|> Map.put("id", @actor_url)
|
||||||
|
|> Map.put("preferredUsername", "anonymous")
|
||||||
|
|
||||||
|
@osmi_actor_url "https://mobilizon.extinctionrebellion.fr/@osmi"
|
||||||
|
@osmi_actor_data @base_actor_data
|
||||||
|
|> Map.put("id", @osmi_actor_url)
|
||||||
|
|> Map.put("preferredUsername", "osmi")
|
||||||
|
|
||||||
|
@xr_nantes_actor_url "https://mobilizon.extinctionrebellion.fr/@xr_nantes"
|
||||||
|
@xr_nantes_actor_data @base_actor_data
|
||||||
|
|> Map.put("id", @xr_nantes_actor_url)
|
||||||
|
|> Map.put("preferredUsername", "xr_nantes")
|
||||||
|
|
||||||
|
@event_url "https://mobilizon.extinctionrebellion.fr/events/d70f8e0d-62dc-4897-a855-ebcbe9798fc1"
|
||||||
|
@event_data File.read!("test/fixtures/mobilizon-post-activity.json")
|
||||||
|
|> Jason.decode!()
|
||||||
|
|> Map.get("object")
|
||||||
|
|> Map.put("id", @event_url)
|
||||||
|
|> Map.put("actor", @osmi_actor_url)
|
||||||
|
|> Map.put("attributedTo", @xr_nantes_actor_url)
|
||||||
|
|> Map.put("tag", [])
|
||||||
|
|
||||||
|
test "When the event is remote" do
|
||||||
|
object = %{
|
||||||
|
"actor" => @actor_url,
|
||||||
|
"id" =>
|
||||||
|
"https://mobilizon.extinctionrebellion.fr/join/event/b67cf172-af23-4ae8-b00e-a2e3643ccb21",
|
||||||
|
"object" =>
|
||||||
|
"https://mobilizon.extinctionrebellion.fr/events/d70f8e0d-62dc-4897-a855-ebcbe9798fc1",
|
||||||
|
"participationMessage" => nil,
|
||||||
|
"published" => "2022-03-28T20:11:11Z",
|
||||||
|
"type" => "Join"
|
||||||
|
}
|
||||||
|
|
||||||
|
activity = %{
|
||||||
|
"type" => "Accept",
|
||||||
|
"object" => object,
|
||||||
|
"actor" => @actor_url,
|
||||||
|
"id" =>
|
||||||
|
"https://mobilizon.extinctionrebellion.fr/join/event/b67cf172-af23-4ae8-b00e-a2e3643ccb21/activity"
|
||||||
|
}
|
||||||
|
|
||||||
|
Mock
|
||||||
|
|> expect(:call, 4, fn
|
||||||
|
%{method: :get, url: @actor_url}, _opts ->
|
||||||
|
{:ok, %Tesla.Env{status: 200, body: @actor_data}}
|
||||||
|
|
||||||
|
%{method: :get, url: @osmi_actor_url}, _opts ->
|
||||||
|
{:ok, %Tesla.Env{status: 200, body: @osmi_actor_data}}
|
||||||
|
|
||||||
|
%{method: :get, url: @xr_nantes_actor_url}, _opts ->
|
||||||
|
{:ok, %Tesla.Env{status: 200, body: @xr_nantes_actor_data}}
|
||||||
|
|
||||||
|
%{method: :get, url: @event_url}, _opts ->
|
||||||
|
{:ok, %Tesla.Env{status: 200, body: @event_data}}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:ok, _activity, _object} = Transmogrifier.handle_incoming(activity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue