From 6cda3c0a94c21e522043d8576dc2af7eb2f14507 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sat, 31 Oct 2020 10:30:03 +0100 Subject: [PATCH] Don't allow remote comments to be inserted if parent event doesn't allow it Signed-off-by: Thomas Citharel --- lib/federation/activity_pub/transmogrifier.ex | 25 +++++++++++-------- lib/federation/activity_pub/types/comments.ex | 20 ++++++++++++++- .../transmogrifier/comments_test.exs | 19 ++++++++++++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/lib/federation/activity_pub/transmogrifier.ex b/lib/federation/activity_pub/transmogrifier.ex index 09e4559ae..c215cd111 100644 --- a/lib/federation/activity_pub/transmogrifier.ex +++ b/lib/federation/activity_pub/transmogrifier.ex @@ -66,22 +66,25 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do object |> Converter.Comment.as_to_model_data(), {:existing_comment, {:error, :comment_not_found}} <- {:existing_comment, Discussions.get_comment_from_url_with_preload(object_data.url)}, - object_data <- transform_object_data_for_discussion(object_data) do - # Check should be better - - {:ok, %Activity{} = activity, entity} = - if is_data_for_comment_or_discussion?(object_data) do - Logger.debug("Chosing to create a regular comment") - ActivityPub.create(:comment, object_data, false) - else - Logger.debug("Chosing to initialize or add a comment to a conversation") - ActivityPub.create(:discussion, object_data, false) - end + object_data <- transform_object_data_for_discussion(object_data), + # Check should be better + {:ok, %Activity{} = activity, entity} <- + (if is_data_for_comment_or_discussion?(object_data) do + Logger.debug("Chosing to create a regular comment") + ActivityPub.create(:comment, object_data, false) + else + Logger.debug("Chosing to initialize or add a comment to a conversation") + ActivityPub.create(:discussion, object_data, false) + end) do {:ok, activity, entity} else {:existing_comment, {:ok, %Comment{} = comment}} -> {:ok, nil, comment} + + {:error, :event_comments_are_closed} -> + Logger.debug("Tried to reply to an event for which comments are closed") + :error end end diff --git a/lib/federation/activity_pub/types/comments.ex b/lib/federation/activity_pub/types/comments.ex index 019a2958a..ee4c206b8 100644 --- a/lib/federation/activity_pub/types/comments.ex +++ b/lib/federation/activity_pub/types/comments.ex @@ -3,7 +3,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do alias Mobilizon.{Actors, Discussions, Events} alias Mobilizon.Actors.Actor alias Mobilizon.Discussions.{Comment, Discussion} - alias Mobilizon.Events.Event + alias Mobilizon.Events.{Event, EventOptions} alias Mobilizon.Federation.ActivityPub.Audience alias Mobilizon.Federation.ActivityPub.Types.Entity alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils @@ -21,6 +21,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do @spec create(map(), map()) :: {:ok, map()} def create(args, additional) do with args <- prepare_args_for_comment(args), + :ok <- make_sure_event_allows_commenting(args), {:ok, %Comment{discussion_id: discussion_id} = comment} <- Discussions.create_comment(args), :ok <- maybe_publish_graphql_subscription(discussion_id), @@ -171,4 +172,21 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do :ok end end + + defp make_sure_event_allows_commenting(%{ + actor_id: actor_id, + event: %Event{ + options: %EventOptions{comment_moderation: comment_moderation}, + organizer_actor_id: organizer_actor_id + } + }) do + if comment_moderation != :closed || + to_string(actor_id) == to_string(organizer_actor_id) do + :ok + else + {:error, :event_comments_are_closed} + end + end + + defp make_sure_event_allows_commenting(_), do: :ok end diff --git a/test/federation/activity_pub/transmogrifier/comments_test.exs b/test/federation/activity_pub/transmogrifier/comments_test.exs index 897d8eab1..34d9e1e69 100644 --- a/test/federation/activity_pub/transmogrifier/comments_test.exs +++ b/test/federation/activity_pub/transmogrifier/comments_test.exs @@ -8,6 +8,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do alias Mobilizon.Actors.Actor alias Mobilizon.Discussions alias Mobilizon.Discussions.Comment + alias Mobilizon.Events.Event alias Mobilizon.Federation.ActivityPub.{Activity, Transmogrifier} alias Mobilizon.Federation.ActivityStream.Convertible alias Mobilizon.Service.HTTP.ActivityPub.Mock @@ -73,6 +74,24 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do assert returned_activity.data["object"]["inReplyTo"] == origin_comment.url end + test "it doesn't saves replies to an event if the event doesn't accept comments" do + data = + File.read!("test/fixtures/mastodon-post-activity.json") + |> Jason.decode!() + + %Event{url: reply_to_url} = insert(:event, options: %{comment_moderation: :closed}) + + object = + data["object"] + |> Map.put("inReplyTo", reply_to_url) + + data = + data + |> Map.put("object", object) + + :error = Transmogrifier.handle_incoming(data) + end + @url_404 "https://404.site/whatever" test "it does not crash if the object in inReplyTo can't be fetched" do data =