fix(backend): only send announcement event emails when the comment author has the right to do so

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2024-01-09 14:49:11 +01:00
parent aa388a7a47
commit 0bd00de501
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
2 changed files with 197 additions and 14 deletions

View file

@ -2,7 +2,7 @@ defmodule Mobilizon.Service.Activity.Conversation do
@moduledoc """
Insert a conversation activity
"""
alias Mobilizon.Conversations
alias Mobilizon.{Actors, Conversations}
alias Mobilizon.Conversations.{Conversation, ConversationParticipant}
alias Mobilizon.Discussions.Comment
alias Mobilizon.Events.Event
@ -38,7 +38,7 @@ defmodule Mobilizon.Service.Activity.Conversation do
%Conversation{
id: conversation_id
} = conversation,
%Comment{actor_id: actor_id, text: last_comment_text},
%Comment{actor_id: actor_id, text: last_comment_text} = comment,
_options
)
when subject in [
@ -55,7 +55,8 @@ defmodule Mobilizon.Service.Activity.Conversation do
actor_id: conversation_participant_actor_id
} =
conversation_participant ->
if actor_id != conversation_participant_actor_id do
if actor_id != conversation_participant_actor_id and
can_send_event_announcement?(conversation, comment) do
LegacyNotifierBuilder.enqueue(
:legacy_notify,
%{
@ -98,4 +99,31 @@ defmodule Mobilizon.Service.Activity.Conversation do
}
defp event_subject_params(_), do: %{}
@spec can_send_event_announcement?(Conversation.t(), Comment.t()) :: boolean()
defp can_send_event_announcement?(
%Conversation{
event: %Event{
attributed_to_id: attributed_to_id
}
},
%Comment{actor_id: actor_id}
)
when not is_nil(attributed_to_id) do
attributed_to_id == actor_id or Actors.member?(actor_id, attributed_to_id)
end
defp can_send_event_announcement?(
%Conversation{
event: %Event{
organizer_actor_id: organizer_actor_id
}
},
%Comment{actor_id: actor_id}
)
when not is_nil(organizer_actor_id) do
organizer_actor_id == actor_id
end
defp can_send_event_announcement?(_, _), do: false
end

View file

@ -7,6 +7,7 @@ defmodule Mobilizon.Service.Activity.ConversationTest do
alias Mobilizon.Conversations
alias Mobilizon.Conversations.{Conversation, ConversationParticipant}
alias Mobilizon.Discussions.Comment
alias Mobilizon.Events.Event
alias Mobilizon.Service.Activity.Conversation, as: ConversationActivity
alias Mobilizon.Service.Workers.LegacyNotifierBuilder
alias Mobilizon.Users.User
@ -15,16 +16,93 @@ defmodule Mobilizon.Service.Activity.ConversationTest do
use Oban.Testing, repo: Mobilizon.Storage.Repo
import Mobilizon.Factory
describe "handle conversation" do
test "with participants" do
describe "handle activity from event private announcement conversation" do
test "when conversation initial comment author is not an organizer" do
%User{} = user = insert(:user)
%Actor{id: actor_id} = actor = insert(:actor, user: user)
%Conversation{
id: conversation_id,
last_comment: %Comment{actor_id: last_comment_actor_id}
} =
conversation = insert(:conversation, event: nil)
%Actor{} = organizer_actor = insert(:actor)
%Event{} = event = insert(:event)
%Comment{} = comment = insert(:comment, actor: organizer_actor)
%Conversation{id: conversation_id} =
conversation =
insert(:conversation, event: event, last_comment: comment, origin_comment: comment)
%ConversationParticipant{id: conversation_participant_actor_id} =
insert(:conversation_participant, actor: actor, conversation: conversation)
%ConversationParticipant{
id: conversation_participant_id,
actor: %Actor{id: conversation_other_participant_actor_id}
} = insert(:conversation_participant, conversation: conversation)
conversation = Conversations.get_conversation(conversation_id)
assert {:ok, _} =
ConversationActivity.insert_activity(conversation, subject: "conversation_created")
refute_enqueued(
worker: LegacyNotifierBuilder,
args: %{
"author_id" => organizer_actor.id,
"participant" => %{"actor_id" => actor_id, "id" => conversation_participant_actor_id},
"object_id" => to_string(conversation_id),
"object_type" => "conversation",
"op" => "legacy_notify",
"subject" => "conversation_created",
"subject_params" => %{
"conversation_id" => conversation_id,
"conversation_participant_id" => conversation_participant_actor_id,
"conversation_event_id" => event.id,
"conversation_event_title" => event.title,
"conversation_event_uuid" => event.uuid
},
"type" => "conversation"
}
)
refute_enqueued(
worker: LegacyNotifierBuilder,
args: %{
"author_id" => organizer_actor.id,
"participant" => %{
"actor_id" => conversation_other_participant_actor_id,
"id" => conversation_participant_id
},
"object_id" => to_string(conversation_id),
"object_type" => "conversation",
"op" => "legacy_notify",
"subject" => "conversation_created",
"subject_params" => %{
"conversation_id" => conversation_id,
"conversation_participant_id" => conversation_participant_id,
"conversation_event_id" => event.id,
"conversation_event_title" => event.title,
"conversation_event_uuid" => event.uuid
},
"type" => "conversation"
}
)
assert [] = all_enqueued()
end
test "an author who is the event organizer" do
%User{} = user = insert(:user)
%Actor{id: actor_id} = actor = insert(:actor, user: user)
%Actor{} = organizer_actor = insert(:actor)
%Event{} = event = insert(:event, organizer_actor: organizer_actor)
%Comment{} = comment = insert(:comment, actor: organizer_actor)
%Conversation{id: conversation_id} =
conversation =
insert(:conversation, event: event, last_comment: comment, origin_comment: comment)
%ConversationParticipant{id: conversation_participant_actor_id} =
insert(:conversation_participant, actor: actor, conversation: conversation)
@ -42,7 +120,7 @@ defmodule Mobilizon.Service.Activity.ConversationTest do
assert_enqueued(
worker: LegacyNotifierBuilder,
args: %{
"author_id" => last_comment_actor_id,
"author_id" => organizer_actor.id,
"participant" => %{"actor_id" => actor_id, "id" => conversation_participant_actor_id},
"object_id" => to_string(conversation_id),
"object_type" => "conversation",
@ -50,7 +128,10 @@ defmodule Mobilizon.Service.Activity.ConversationTest do
"subject" => "conversation_created",
"subject_params" => %{
"conversation_id" => conversation_id,
"conversation_participant_id" => conversation_participant_actor_id
"conversation_participant_id" => conversation_participant_actor_id,
"conversation_event_id" => event.id,
"conversation_event_title" => event.title,
"conversation_event_uuid" => event.uuid
},
"type" => "conversation"
}
@ -59,7 +140,7 @@ defmodule Mobilizon.Service.Activity.ConversationTest do
assert_enqueued(
worker: LegacyNotifierBuilder,
args: %{
"author_id" => last_comment_actor_id,
"author_id" => organizer_actor.id,
"participant" => %{
"actor_id" => conversation_other_participant_actor_id,
"id" => conversation_participant_id
@ -70,7 +151,81 @@ defmodule Mobilizon.Service.Activity.ConversationTest do
"subject" => "conversation_created",
"subject_params" => %{
"conversation_id" => conversation_id,
"conversation_participant_id" => conversation_participant_id
"conversation_participant_id" => conversation_participant_id,
"conversation_event_id" => event.id,
"conversation_event_title" => event.title,
"conversation_event_uuid" => event.uuid
},
"type" => "conversation"
}
)
end
test "an author who is member of the event organizer group" do
%User{} = user = insert(:user)
%Actor{id: actor_id} = actor = insert(:actor, user: user)
%Actor{} = organizer_group = insert(:group)
%Event{} = event = insert(:event, attributed_to: organizer_group)
%Comment{} = comment = insert(:comment, actor: organizer_group)
%Conversation{id: conversation_id} =
conversation =
insert(:conversation, event: event, last_comment: comment, origin_comment: comment)
%ConversationParticipant{id: conversation_participant_actor_id} =
insert(:conversation_participant, actor: actor, conversation: conversation)
%ConversationParticipant{
id: conversation_participant_id,
actor: %Actor{id: conversation_other_participant_actor_id}
} = insert(:conversation_participant, conversation: conversation)
conversation = Conversations.get_conversation(conversation_id)
assert {:ok, _} =
ConversationActivity.insert_activity(conversation, subject: "conversation_created")
assert_enqueued(
worker: LegacyNotifierBuilder,
args: %{
"author_id" => organizer_group.id,
"participant" => %{"actor_id" => actor_id, "id" => conversation_participant_actor_id},
"object_id" => to_string(conversation_id),
"object_type" => "conversation",
"op" => "legacy_notify",
"subject" => "conversation_created",
"subject_params" => %{
"conversation_id" => conversation_id,
"conversation_participant_id" => conversation_participant_actor_id,
"conversation_event_id" => event.id,
"conversation_event_title" => event.title,
"conversation_event_uuid" => event.uuid
},
"type" => "conversation"
}
)
assert_enqueued(
worker: LegacyNotifierBuilder,
args: %{
"author_id" => organizer_group.id,
"participant" => %{
"actor_id" => conversation_other_participant_actor_id,
"id" => conversation_participant_id
},
"object_id" => to_string(conversation_id),
"object_type" => "conversation",
"op" => "legacy_notify",
"subject" => "conversation_created",
"subject_params" => %{
"conversation_id" => conversation_id,
"conversation_participant_id" => conversation_participant_id,
"conversation_event_id" => event.id,
"conversation_event_title" => event.title,
"conversation_event_uuid" => event.uuid
},
"type" => "conversation"
}