Make sure remote Update activities can't affect local actors other than
Groups Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
4b869a6015
commit
00f4c0b02c
|
@ -28,7 +28,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Update do
|
|||
Logger.debug("updating an activity")
|
||||
Logger.debug(inspect(args))
|
||||
|
||||
case Managable.update(old_entity, args, additional) do
|
||||
case Managable.update(old_entity, args, Map.put(additional, :local, local)) do
|
||||
{:ok, entity, update_data} ->
|
||||
{:ok, activity} = create_activity(update_data, local)
|
||||
maybe_federate(activity)
|
||||
|
|
|
@ -407,6 +407,13 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
Actions.Update.update(old_actor, object_data, false, %{updater_actor: author}) do
|
||||
{:ok, activity, new_actor}
|
||||
else
|
||||
{:error, :update_not_allowed} ->
|
||||
Logger.warn("Activity tried to update an actor that's local or not a group",
|
||||
activity: params
|
||||
)
|
||||
|
||||
:error
|
||||
|
||||
e ->
|
||||
Sentry.capture_message("Error while handling an Update activity",
|
||||
extra: %{params: params}
|
||||
|
|
|
@ -45,25 +45,30 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
|
|||
def update(%Actor{} = old_actor, args, additional) do
|
||||
updater_actor = Map.get(args, :updater_actor) || Map.get(additional, :updater_actor)
|
||||
|
||||
case Actors.update_actor(old_actor, args) do
|
||||
{:ok, %Actor{} = new_actor} ->
|
||||
GroupActivity.insert_activity(new_actor,
|
||||
subject: "group_updated",
|
||||
old_group: old_actor,
|
||||
updater_actor: updater_actor
|
||||
)
|
||||
if Map.get(additional, :local, false) == true or not match?(%Actor{domain: nil}, old_actor) or
|
||||
match?(%Actor{type: :Group}, old_actor) do
|
||||
case Actors.update_actor(old_actor, args) do
|
||||
{:ok, %Actor{} = new_actor} ->
|
||||
GroupActivity.insert_activity(new_actor,
|
||||
subject: "group_updated",
|
||||
old_group: old_actor,
|
||||
updater_actor: updater_actor
|
||||
)
|
||||
|
||||
actor_as_data = Convertible.model_to_as(new_actor)
|
||||
Cachex.del(:activity_pub, "actor_#{new_actor.preferred_username}")
|
||||
audience = Audience.get_audience(new_actor)
|
||||
actor_as_data = Convertible.model_to_as(new_actor)
|
||||
Cachex.del(:activity_pub, "actor_#{new_actor.preferred_username}")
|
||||
audience = Audience.get_audience(new_actor)
|
||||
|
||||
additional = Map.merge(additional, %{"actor" => (updater_actor || old_actor).url})
|
||||
additional = Map.merge(additional, %{"actor" => (updater_actor || old_actor).url})
|
||||
|
||||
update_data = make_update_data(actor_as_data, Map.merge(audience, additional))
|
||||
{:ok, new_actor, update_data}
|
||||
update_data = make_update_data(actor_as_data, Map.merge(audience, additional))
|
||||
{:ok, new_actor, update_data}
|
||||
|
||||
{:error, %Ecto.Changeset{} = err} ->
|
||||
{:error, err}
|
||||
{:error, %Ecto.Changeset{} = err} ->
|
||||
{:error, err}
|
||||
end
|
||||
else
|
||||
{:error, :update_not_allowed}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ defmodule Mobilizon.Federation.ActivityPubTest do
|
|||
actor = insert(:actor)
|
||||
actor_data = %{summary: @updated_actor_summary}
|
||||
|
||||
{:ok, update, _} = Actions.Update.update(actor, actor_data, false)
|
||||
{:ok, update, _} = Actions.Update.update(actor, actor_data, true)
|
||||
|
||||
assert update.data["actor"] == actor.url
|
||||
assert update.data["to"] == [@activity_pub_public_audience]
|
||||
|
|
|
@ -3,12 +3,13 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.UpdateTest do
|
|||
use Oban.Testing, repo: Mobilizon.Storage.Repo
|
||||
import Mobilizon.Factory
|
||||
import Mox
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
alias Mobilizon.{Actors, Events, Posts}
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier}
|
||||
alias Mobilizon.Federation.ActivityPub.{Activity, Relay, Transmogrifier}
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
alias Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||
|
||||
|
@ -50,6 +51,29 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.UpdateTest do
|
|||
assert actor.summary == "<p>Some bio</p>"
|
||||
end
|
||||
|
||||
test "it fails for incoming update activies on local actors" do
|
||||
%Actor{url: relay_actor_url} = Relay.get_actor()
|
||||
|
||||
update_data = File.read!("test/fixtures/mastodon-update.json") |> Jason.decode!()
|
||||
|
||||
object =
|
||||
update_data["object"]
|
||||
|> Map.put("actor", relay_actor_url)
|
||||
|> Map.put("id", relay_actor_url)
|
||||
|
||||
update_data =
|
||||
update_data
|
||||
|> Map.put("actor", relay_actor_url)
|
||||
|> Map.put("object", object)
|
||||
|
||||
assert capture_log([level: :warn], fn ->
|
||||
:error = Transmogrifier.handle_incoming(update_data)
|
||||
end) =~ "[warning] Activity tried to update an actor that's local or not a group"
|
||||
|
||||
{:ok, %Actor{keys: keys}} = Actors.get_actor_by_url(relay_actor_url)
|
||||
assert Regex.match?(~r/BEGIN RSA PRIVATE KEY/, keys)
|
||||
end
|
||||
|
||||
test "it works for incoming update activities on events" do
|
||||
data = File.read!("test/fixtures/mobilizon-post-activity.json") |> Jason.decode!()
|
||||
|
||||
|
|
Loading…
Reference in a new issue