95 lines
3.3 KiB
Elixir
95 lines
3.3 KiB
Elixir
defmodule Mobilizon.GraphQL.Resolvers.Member do
|
|
@moduledoc """
|
|
Handles the member-related GraphQL calls
|
|
"""
|
|
|
|
alias Mobilizon.{Actors, Users}
|
|
alias Mobilizon.Actors.{Actor, Member}
|
|
alias Mobilizon.Federation.ActivityPub
|
|
alias Mobilizon.Storage.Page
|
|
alias Mobilizon.Users.User
|
|
|
|
@doc """
|
|
Find members for group.
|
|
|
|
If actor requesting is not part of the group, we only return the number of members, not members
|
|
"""
|
|
def find_members_for_group(
|
|
%Actor{id: group_id} = group,
|
|
_args,
|
|
%{
|
|
context: %{current_user: %User{} = user}
|
|
} = _resolution
|
|
) do
|
|
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
|
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
|
%Page{} = page <- Actors.list_members_for_group(group) do
|
|
{:ok, page}
|
|
else
|
|
{:member, false} ->
|
|
# Actor is not member of group, fallback to public
|
|
with %Page{} = page <- Actors.list_members_for_group(group) do
|
|
{:ok, %Page{page | elements: []}}
|
|
end
|
|
end
|
|
end
|
|
|
|
def find_members_for_group(%Actor{} = group, _args, _resolution) do
|
|
with %Page{} = page <- Actors.list_members_for_group(group) do
|
|
{:ok, %Page{page | elements: []}}
|
|
end
|
|
end
|
|
|
|
def invite_member(
|
|
_parent,
|
|
%{group_id: group_id, target_actor_username: target_actor_username},
|
|
%{context: %{current_user: %User{} = user}}
|
|
) do
|
|
with %Actor{id: actor_id} = actor <- Users.get_actor_for_user(user),
|
|
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
|
|
{:has_rights_to_invite, {:ok, %Member{role: role}}}
|
|
when role in [:moderator, :administrator, :creator] <-
|
|
{:has_rights_to_invite, Actors.get_member(actor_id, group_id)},
|
|
{:target_actor_username, {:ok, %Actor{id: target_actor_id} = target_actor}} <-
|
|
{:target_actor_username,
|
|
ActivityPub.find_or_make_actor_from_nickname(target_actor_username)},
|
|
{:error, :member_not_found} <- Actors.get_member(target_actor_id, group.id),
|
|
{:ok, _activity, %Member{} = member} <- ActivityPub.invite(group, actor, target_actor) do
|
|
{:ok, member}
|
|
else
|
|
{:is_owned, nil} ->
|
|
{:error, "Actor id is not owned by authenticated user"}
|
|
|
|
{:error, :group_not_found} ->
|
|
{:error, "Group id not found"}
|
|
|
|
{:target_actor_username, _} ->
|
|
{:error, "Actor invited doesn't exist"}
|
|
|
|
{:has_rights_to_invite, {:error, :member_not_found}} ->
|
|
{:error, "You are not a member of this group"}
|
|
|
|
{:has_rights_to_invite, _} ->
|
|
{:error, "You cannot invite to this group"}
|
|
|
|
{:ok, %Member{}} ->
|
|
{:error, "Actor is already a member of this group"}
|
|
end
|
|
end
|
|
|
|
def accept_invitation(_parent, %{id: member_id}, %{context: %{current_user: %User{} = user}}) do
|
|
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
|
|
%Member{actor: %Actor{id: member_actor_id}} = member <- Actors.get_member(member_id),
|
|
{:is_same_actor, true} <- {:is_same_actor, member_actor_id === actor_id},
|
|
{:ok, _activity, %Member{} = member} <-
|
|
ActivityPub.accept(
|
|
:invite,
|
|
member,
|
|
true
|
|
) do
|
|
# Launch an async task to refresh the group profile, fetch resources, discussions, members
|
|
{:ok, member}
|
|
end
|
|
end
|
|
end
|