diff --git a/lib/federation/activity_pub/transmogrifier.ex b/lib/federation/activity_pub/transmogrifier.ex
index e7c06ce12..0ebd70a04 100644
--- a/lib/federation/activity_pub/transmogrifier.ex
+++ b/lib/federation/activity_pub/transmogrifier.ex
@@ -870,7 +870,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
        when role in [:not_approved, :rejected] do
     with %Event{} = event <- Events.get_event_with_preload!(event.id),
          {:can_accept_event_join, true} <-
-           {:can_accept_event_join, can_accept_event_join?(actor_accepting, event)},
+           {:can_accept_event_join, can_manage_event?(actor_accepting, event)},
          {:ok, %Activity{} = activity, %Participant{role: :participant} = participant} <-
            ActivityPub.accept(
              :join,
@@ -918,9 +918,9 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
     with {:join_event, {:ok, %Participant{event: event, role: role} = participant}}
          when role != :rejected <-
            {:join_event, get_participant(join_object, actor_accepting)},
-         # TODO: The actor that accepts the Join activity may another one that the event organizer ?
-         # Or maybe for groups it's the group that sends the Accept activity
-         {:same_actor, true} <- {:same_actor, actor_accepting.id == event.organizer_actor_id},
+         {:event, %Event{} = event} <- {:event, Events.get_event_with_preload!(event.id)},
+         {:can_accept_event_reject, true} <-
+           {:can_accept_event_reject, can_manage_event?(actor_accepting, event)},
          {:ok, activity, participant} <-
            ActivityPub.reject(:join, participant, false),
          :ok <- Participation.send_emails_to_local_user(participant) do
@@ -1142,21 +1142,21 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
     end
   end
 
-  defp can_accept_event_join?(
+  defp can_manage_event?(
          %Actor{url: actor_url} = actor,
          %Event{attributed_to: %Actor{type: :Group, url: group_url} = _group} = event
        ) do
     actor_url == group_url || Permission.can_update_group_object?(actor, event)
   end
 
-  defp can_accept_event_join?(
+  defp can_manage_event?(
          %Actor{id: actor_id},
          %Event{organizer_actor: %Actor{id: organizer_actor_id}}
        ) do
     organizer_actor_id == actor_id
   end
 
-  defp can_accept_event_join?(_actor, _event) do
+  defp can_manage_event?(_actor, _event) do
     false
   end
 end
diff --git a/lib/graphql/api/participations.ex b/lib/graphql/api/participations.ex
index 8d89c7b52..55ce95c11 100644
--- a/lib/graphql/api/participations.ex
+++ b/lib/graphql/api/participations.ex
@@ -75,6 +75,7 @@ defmodule Mobilizon.GraphQL.API.Participations do
            ActivityPub.reject(
              :join,
              participation,
+             true,
              %{"actor" => moderator.url}
            ),
          :ok <- Participation.send_emails_to_local_user(participation) do
diff --git a/lib/graphql/resolvers/event.ex b/lib/graphql/resolvers/event.ex
index 5cebe5e13..318bd75ed 100644
--- a/lib/graphql/resolvers/event.ex
+++ b/lib/graphql/resolvers/event.ex
@@ -15,6 +15,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
   alias Mobilizon.Federation.ActivityPub.Permission
   import Mobilizon.Users.Guards, only: [is_moderator: 1]
   import Mobilizon.Web.Gettext
+  import Mobilizon.GraphQL.Resolvers.Event.Utils
 
   # We limit the max number of events that can be retrieved
   @event_max_limit 100
@@ -133,14 +134,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
   List participants for event (through an event request)
   """
   def list_participants_for_event(
-        %Event{id: event_id},
+        %Event{id: event_id} = event,
         %{page: page, limit: limit, roles: roles},
         %{context: %{current_user: %User{} = user}} = _resolution
       ) do
-    with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
+    with %Actor{} = actor <- Users.get_actor_for_user(user),
          # Check that moderator has right
-         {:actor_approve_permission, true} <-
-           {:actor_approve_permission, Events.moderator_for_event?(event_id, actor_id)} do
+         {:event_can_be_managed, true} <-
+           {:event_can_be_managed, can_event_be_updated_by?(event, actor)} do
       roles =
         case roles do
           nil ->
@@ -159,7 +160,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
       participants = Events.list_participants_for_event(event_id, roles, page, limit)
       {:ok, participants}
     else
-      {:actor_approve_permission, _} ->
+      {:event_can_be_managed, _} ->
         {:error,
          dgettext("errors", "Provided profile doesn't have moderator permissions on this event")}
     end
@@ -414,29 +415,4 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
       {:ok, args}
     end
   end
-
-  defp can_event_be_updated_by?(
-         %Event{attributed_to: %Actor{type: :Group}} = event,
-         %Actor{} = actor_member
-       ) do
-    Permission.can_update_group_object?(actor_member, event)
-  end
-
-  defp can_event_be_updated_by?(
-         %Event{} = event,
-         %Actor{id: actor_member_id}
-       ) do
-    Event.can_be_managed_by?(event, actor_member_id)
-  end
-
-  defp can_event_be_deleted_by?(
-         %Event{attributed_to: %Actor{type: :Group}} = event,
-         %Actor{} = actor_member
-       ) do
-    Permission.can_delete_group_object?(actor_member, event)
-  end
-
-  defp can_event_be_deleted_by?(%Event{} = event, %Actor{id: actor_member_id}) do
-    Event.can_be_managed_by?(event, actor_member_id)
-  end
 end
diff --git a/lib/graphql/resolvers/event/utils.ex b/lib/graphql/resolvers/event/utils.ex
new file mode 100644
index 000000000..e6c7e8c24
--- /dev/null
+++ b/lib/graphql/resolvers/event/utils.ex
@@ -0,0 +1,34 @@
+defmodule Mobilizon.GraphQL.Resolvers.Event.Utils do
+  @moduledoc """
+  Tools to test permission on events
+  """
+
+  alias Mobilizon.Actors.Actor
+  alias Mobilizon.Events.Event
+  alias Mobilizon.Federation.ActivityPub.Permission
+
+  def can_event_be_updated_by?(
+        %Event{attributed_to: %Actor{type: :Group}} = event,
+        %Actor{} = actor_member
+      ) do
+    Permission.can_update_group_object?(actor_member, event)
+  end
+
+  def can_event_be_updated_by?(
+        %Event{} = event,
+        %Actor{id: actor_member_id}
+      ) do
+    Event.can_be_managed_by?(event, actor_member_id)
+  end
+
+  def can_event_be_deleted_by?(
+        %Event{attributed_to: %Actor{type: :Group}} = event,
+        %Actor{} = actor_member
+      ) do
+    Permission.can_delete_group_object?(actor_member, event)
+  end
+
+  def can_event_be_deleted_by?(%Event{} = event, %Actor{id: actor_member_id}) do
+    Event.can_be_managed_by?(event, actor_member_id)
+  end
+end
diff --git a/lib/graphql/resolvers/participant.ex b/lib/graphql/resolvers/participant.ex
index d09259eb4..9c41217fb 100644
--- a/lib/graphql/resolvers/participant.ex
+++ b/lib/graphql/resolvers/participant.ex
@@ -11,6 +11,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
   alias Mobilizon.Web.Email.Checker
   require Logger
   import Mobilizon.Web.Gettext
+  import Mobilizon.GraphQL.Resolvers.Event.Utils
 
   @doc """
   Join an event for an regular or anonymous actor
@@ -213,15 +214,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
         }
       ) do
     # Check that moderator provided is rightly authenticated
-    with %Actor{id: moderator_actor_id} = moderator_actor <- Users.get_actor_for_user(user),
+    with %Actor{} = moderator_actor <- Users.get_actor_for_user(user),
          # Check that participation already exists
-         {:has_participation, %Participant{role: old_role} = participation} <-
+         {:has_participation, %Participant{role: old_role, event_id: event_id} = participation} <-
            {:has_participation, Events.get_participant(participation_id)},
          {:same_role, false} <- {:same_role, new_role == old_role},
          # Check that moderator has right
-         {:actor_approve_permission, true} <-
-           {:actor_approve_permission,
-            Events.moderator_for_event?(participation.event.id, moderator_actor_id)},
+         {:event, %Event{} = event} <- {:event, Events.get_event_with_preload!(event_id)},
+         {:event_can_be_managed, true} <-
+           {:event_can_be_managed, can_event_be_updated_by?(event, moderator_actor)},
          {:ok, _activity, participation} <-
            Participations.update(participation, moderator_actor, new_role) do
       {:ok, participation}
@@ -229,7 +230,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
       {:has_participation, nil} ->
         {:error, dgettext("errors", "Participant not found")}
 
-      {:actor_approve_permission, _} ->
+      {:event_can_be_managed, _} ->
         {:error,
          dgettext("errors", "Provided profile doesn't have moderator permissions on this event")}