Fix remote group moderators managing event participations
Closes #827 Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
117f8e4339
commit
e05735265b
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
34
lib/graphql/resolvers/event/utils.ex
Normal file
34
lib/graphql/resolvers/event/utils.ex
Normal file
@ -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
|
@ -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")}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user