2020-01-26 19:34:25 +00:00
|
|
|
|
defmodule Mobilizon.GraphQL.Resolvers.Group do
|
2019-01-03 13:59:59 +00:00
|
|
|
|
@moduledoc """
|
2019-09-22 14:26:23 +00:00
|
|
|
|
Handles the group-related GraphQL calls.
|
2019-01-03 13:59:59 +00:00
|
|
|
|
"""
|
2019-09-22 14:26:23 +00:00
|
|
|
|
|
2020-08-27 09:53:24 +00:00
|
|
|
|
import Mobilizon.Users.Guards
|
2021-10-06 16:00:50 +00:00
|
|
|
|
alias Mobilizon.Config
|
2021-09-10 09:35:32 +00:00
|
|
|
|
alias Mobilizon.{Actors, Events}
|
2021-10-22 09:40:47 +00:00
|
|
|
|
alias Mobilizon.Actors.{Actor, Follower, Member}
|
2021-09-28 17:40:37 +00:00
|
|
|
|
alias Mobilizon.Federation.ActivityPub.Actions
|
2021-04-22 10:17:56 +00:00
|
|
|
|
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
|
2020-01-26 20:11:16 +00:00
|
|
|
|
alias Mobilizon.GraphQL.API
|
2021-10-11 15:13:57 +00:00
|
|
|
|
alias Mobilizon.Users.{User, UserRole}
|
2020-09-29 07:53:48 +00:00
|
|
|
|
alias Mobilizon.Web.Upload
|
|
|
|
|
import Mobilizon.Web.Gettext
|
2020-01-22 01:14:42 +00:00
|
|
|
|
|
2018-12-03 10:58:57 +00:00
|
|
|
|
require Logger
|
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec find_group(
|
|
|
|
|
any,
|
|
|
|
|
%{:preferred_username => binary, optional(any) => any},
|
|
|
|
|
Absinthe.Resolution.t()
|
|
|
|
|
) ::
|
|
|
|
|
{:error, :group_not_found} | {:ok, Actor.t()}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
@doc """
|
|
|
|
|
Find a group
|
|
|
|
|
"""
|
|
|
|
|
def find_group(
|
|
|
|
|
parent,
|
|
|
|
|
%{preferred_username: name} = args,
|
|
|
|
|
%{
|
|
|
|
|
context: %{
|
2021-09-10 09:35:32 +00:00
|
|
|
|
current_actor: %Actor{id: actor_id}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
) do
|
2021-09-28 17:40:37 +00:00
|
|
|
|
case ActivityPubActor.find_or_make_group_from_nickname(name) do
|
|
|
|
|
{:ok, %Actor{id: group_id, suspended: false} = group} ->
|
|
|
|
|
if Actors.is_member?(actor_id, group_id) do
|
|
|
|
|
{:ok, group}
|
|
|
|
|
else
|
|
|
|
|
find_group(parent, args, nil)
|
|
|
|
|
end
|
2020-02-18 07:57:00 +00:00
|
|
|
|
|
2021-09-30 07:26:29 +00:00
|
|
|
|
{:ok, %Actor{}} ->
|
|
|
|
|
{:error, :group_not_found}
|
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
{:error, _err} ->
|
2020-10-12 10:16:36 +00:00
|
|
|
|
{:error, :group_not_found}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-12-03 10:58:57 +00:00
|
|
|
|
def find_group(_parent, %{preferred_username: name}, _resolution) do
|
2021-09-28 17:40:37 +00:00
|
|
|
|
case ActivityPubActor.find_or_make_group_from_nickname(name) do
|
|
|
|
|
{:ok, %Actor{suspended: false} = actor} ->
|
|
|
|
|
%Actor{} = actor = restrict_fields_for_non_member_request(actor)
|
|
|
|
|
{:ok, actor}
|
|
|
|
|
|
2021-09-30 07:26:29 +00:00
|
|
|
|
{:ok, %Actor{}} ->
|
|
|
|
|
{:error, :group_not_found}
|
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
{:error, _err} ->
|
2020-10-12 10:16:36 +00:00
|
|
|
|
{:error, :group_not_found}
|
2018-12-03 10:58:57 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-08-27 09:53:24 +00:00
|
|
|
|
@doc """
|
|
|
|
|
Get a group
|
|
|
|
|
"""
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec get_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Actor.t()} | {:error, String.t()}
|
2020-08-27 09:53:24 +00:00
|
|
|
|
def get_group(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}}) do
|
2021-09-28 17:40:37 +00:00
|
|
|
|
case Actors.get_actor_with_preload(id, true) do
|
|
|
|
|
%Actor{type: :Group, suspended: suspended} = actor ->
|
|
|
|
|
if suspended == false or is_moderator(role) do
|
|
|
|
|
{:ok, actor}
|
|
|
|
|
else
|
|
|
|
|
{:error, dgettext("errors", "Group with ID %{id} not found", id: id)}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
nil ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "Group with ID %{id} not found", id: id)}
|
2020-08-27 09:53:24 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-12-03 10:58:57 +00:00
|
|
|
|
@doc """
|
|
|
|
|
Lists all groups
|
|
|
|
|
"""
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec list_groups(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Page.t(Actor.t())} | {:error, String.t()}
|
2020-08-27 09:53:24 +00:00
|
|
|
|
def list_groups(
|
|
|
|
|
_parent,
|
|
|
|
|
%{
|
|
|
|
|
preferred_username: preferred_username,
|
|
|
|
|
name: name,
|
|
|
|
|
domain: domain,
|
|
|
|
|
local: local,
|
|
|
|
|
suspended: suspended,
|
|
|
|
|
page: page,
|
|
|
|
|
limit: limit
|
|
|
|
|
},
|
|
|
|
|
%{
|
|
|
|
|
context: %{current_user: %User{role: role}}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
when is_moderator(role) do
|
|
|
|
|
{:ok,
|
|
|
|
|
Actors.list_actors(:Group, preferred_username, name, domain, local, suspended, page, limit)}
|
2018-12-03 10:58:57 +00:00
|
|
|
|
end
|
|
|
|
|
|
2020-08-27 09:53:24 +00:00
|
|
|
|
def list_groups(_parent, _args, _resolution),
|
2020-09-29 07:53:48 +00:00
|
|
|
|
do: {:error, dgettext("errors", "You may not list groups unless moderator.")}
|
|
|
|
|
|
|
|
|
|
# TODO Move me to somewhere cleaner
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec save_attached_pictures(map()) :: map()
|
2020-09-29 07:53:48 +00:00
|
|
|
|
defp save_attached_pictures(args) do
|
|
|
|
|
Enum.reduce([:avatar, :banner], args, fn key, args ->
|
2021-04-12 08:13:45 +00:00
|
|
|
|
if is_map(args) && Map.has_key?(args, key) && !is_nil(args[key][:media]) do
|
2020-11-26 10:41:13 +00:00
|
|
|
|
pic = args[key][:media]
|
2020-09-29 07:53:48 +00:00
|
|
|
|
|
|
|
|
|
with {:ok, %{name: name, url: url, content_type: content_type, size: _size}} <-
|
|
|
|
|
Upload.store(pic.file, type: key, description: pic.alt) do
|
|
|
|
|
Map.put(args, key, %{"name" => name, "url" => url, "mediaType" => content_type})
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
args
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
end
|
2020-08-27 09:53:24 +00:00
|
|
|
|
|
2018-12-03 10:58:57 +00:00
|
|
|
|
@doc """
|
|
|
|
|
Create a new group. The creator is automatically added as admin
|
|
|
|
|
"""
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec create_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Actor.t()} | {:error, String.t()}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
def create_group(
|
|
|
|
|
_parent,
|
|
|
|
|
args,
|
|
|
|
|
%{
|
|
|
|
|
context: %{
|
2021-10-06 16:00:50 +00:00
|
|
|
|
current_actor: %Actor{id: creator_actor_id} = creator_actor,
|
|
|
|
|
current_user: %User{role: role} = _resolution
|
2020-02-18 07:57:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
) do
|
2021-10-11 15:13:57 +00:00
|
|
|
|
if can_create_group?(role) do
|
|
|
|
|
args =
|
|
|
|
|
args
|
|
|
|
|
|> Map.update(:preferred_username, "", &String.downcase/1)
|
|
|
|
|
|> Map.put(:creator_actor, creator_actor)
|
|
|
|
|
|> Map.put(:creator_actor_id, creator_actor_id)
|
|
|
|
|
|
|
|
|
|
with {:picture, args} when is_map(args) <- {:picture, save_attached_pictures(args)},
|
2021-10-06 16:00:50 +00:00
|
|
|
|
{:ok, _activity, %Actor{type: :Group} = group} <-
|
|
|
|
|
API.Groups.create_group(args) do
|
|
|
|
|
{:ok, group}
|
|
|
|
|
else
|
|
|
|
|
{:picture, {:error, :file_too_large}} ->
|
|
|
|
|
{:error, dgettext("errors", "The provided picture is too heavy")}
|
2021-04-12 08:13:45 +00:00
|
|
|
|
|
2021-10-06 16:00:50 +00:00
|
|
|
|
{:error, err} when is_binary(err) ->
|
|
|
|
|
{:error, err}
|
|
|
|
|
end
|
2021-10-11 15:13:57 +00:00
|
|
|
|
else
|
|
|
|
|
{:error, dgettext("errors", "Only admins can create groups")}
|
2018-12-03 10:58:57 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def create_group(_parent, _args, _resolution) do
|
|
|
|
|
{:error, "You need to be logged-in to create a group"}
|
|
|
|
|
end
|
2019-01-25 08:23:44 +00:00
|
|
|
|
|
2021-10-11 15:13:57 +00:00
|
|
|
|
@spec can_create_group?(UserRole.t()) :: boolean()
|
|
|
|
|
defp can_create_group?(role) do
|
|
|
|
|
if Config.only_admin_can_create_groups?() do
|
|
|
|
|
is_admin(role)
|
|
|
|
|
else
|
|
|
|
|
true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-07-09 15:24:28 +00:00
|
|
|
|
@doc """
|
2020-10-09 13:26:37 +00:00
|
|
|
|
Update a group. The creator is automatically added as admin
|
2020-07-09 15:24:28 +00:00
|
|
|
|
"""
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec update_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Actor.t()} | {:error, String.t()}
|
2020-07-09 15:24:28 +00:00
|
|
|
|
def update_group(
|
|
|
|
|
_parent,
|
2020-10-09 13:26:37 +00:00
|
|
|
|
%{id: group_id} = args,
|
2020-07-09 15:24:28 +00:00
|
|
|
|
%{
|
|
|
|
|
context: %{
|
2021-09-10 09:35:32 +00:00
|
|
|
|
current_actor: %Actor{} = updater_actor
|
2020-07-09 15:24:28 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
) do
|
2021-09-28 17:40:37 +00:00
|
|
|
|
if Actors.is_administrator?(updater_actor.id, group_id) do
|
|
|
|
|
args = Map.put(args, :updater_actor, updater_actor)
|
2021-04-12 08:13:45 +00:00
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
case save_attached_pictures(args) do
|
|
|
|
|
{:error, :file_too_large} ->
|
|
|
|
|
{:error, dgettext("errors", "The provided picture is too heavy")}
|
|
|
|
|
|
|
|
|
|
map when is_map(map) ->
|
|
|
|
|
case API.Groups.update_group(args) do
|
|
|
|
|
{:ok, _activity, %Actor{type: :Group} = group} ->
|
|
|
|
|
{:ok, group}
|
2020-07-09 15:24:28 +00:00
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
{:error, _err} ->
|
|
|
|
|
{:error, dgettext("errors", "Failed to update the group")}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
{:error, dgettext("errors", "Profile is not administrator for the group")}
|
2020-07-09 15:24:28 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def update_group(_parent, _args, _resolution) do
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "You need to be logged-in to update a group")}
|
2020-07-09 15:24:28 +00:00
|
|
|
|
end
|
|
|
|
|
|
2019-01-25 08:23:44 +00:00
|
|
|
|
@doc """
|
|
|
|
|
Delete an existing group
|
|
|
|
|
"""
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec delete_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, %{id: integer()}} | {:error, String.t()}
|
2019-01-25 08:23:44 +00:00
|
|
|
|
def delete_group(
|
|
|
|
|
_parent,
|
2020-08-27 09:53:24 +00:00
|
|
|
|
%{group_id: group_id},
|
2020-02-18 07:57:00 +00:00
|
|
|
|
%{
|
|
|
|
|
context: %{
|
2021-09-10 09:35:32 +00:00
|
|
|
|
current_actor: %Actor{id: actor_id} = actor
|
2020-02-18 07:57:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-25 08:23:44 +00:00
|
|
|
|
) do
|
2021-09-10 09:35:32 +00:00
|
|
|
|
with {:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
|
2019-09-08 22:52:49 +00:00
|
|
|
|
{:ok, %Member{} = member} <- Actors.get_member(actor_id, group.id),
|
2020-02-18 07:57:00 +00:00
|
|
|
|
{:is_admin, true} <- {:is_admin, Member.is_administrator(member)},
|
2021-09-28 17:40:37 +00:00
|
|
|
|
{:ok, _activity, group} <- Actions.Delete.delete(group, actor, true) do
|
2019-01-25 08:23:44 +00:00
|
|
|
|
{:ok, %{id: group.id}}
|
|
|
|
|
else
|
|
|
|
|
{:error, :group_not_found} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "Group not found")}
|
2019-01-25 08:23:44 +00:00
|
|
|
|
|
|
|
|
|
{:error, :member_not_found} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "Current profile is not a member of this group")}
|
2019-01-25 08:23:44 +00:00
|
|
|
|
|
|
|
|
|
{:is_admin, false} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error,
|
|
|
|
|
dgettext("errors", "Current profile is not an administrator of the selected group")}
|
2019-01-25 08:23:44 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def delete_group(_parent, _args, _resolution) do
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "You need to be logged-in to delete a group")}
|
2019-01-25 08:23:44 +00:00
|
|
|
|
end
|
2019-03-01 16:11:28 +00:00
|
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
|
Join an existing group
|
|
|
|
|
"""
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec join_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Member.t()} | {:error, String.t()}
|
2020-11-06 10:34:32 +00:00
|
|
|
|
def join_group(_parent, %{group_id: group_id} = args, %{
|
2021-09-10 09:35:32 +00:00
|
|
|
|
context: %{current_actor: %Actor{} = actor}
|
2020-11-06 10:34:32 +00:00
|
|
|
|
}) do
|
2021-09-10 09:35:32 +00:00
|
|
|
|
with {:ok, %Actor{type: :Group} = group} <-
|
2020-11-06 10:34:32 +00:00
|
|
|
|
Actors.get_group_by_actor_id(group_id),
|
2019-09-08 22:52:49 +00:00
|
|
|
|
{:error, :member_not_found} <- Actors.get_member(actor.id, group.id),
|
2019-03-01 16:11:28 +00:00
|
|
|
|
{:is_able_to_join, true} <- {:is_able_to_join, Member.can_be_joined(group)},
|
2020-11-06 10:34:32 +00:00
|
|
|
|
{:ok, _activity, %Member{} = member} <-
|
2021-09-28 17:40:37 +00:00
|
|
|
|
Actions.Join.join(group, actor, true, args) do
|
2020-11-06 10:34:32 +00:00
|
|
|
|
{:ok, member}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
else
|
|
|
|
|
{:error, :group_not_found} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "Group not found")}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
|
|
|
|
|
{:is_able_to_join, false} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "You cannot join this group")}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
|
|
|
|
|
{:ok, %Member{}} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "You are already a member of this group")}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def join_group(_parent, _args, _resolution) do
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "You need to be logged-in to join a group")}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
|
Leave a existing group
|
|
|
|
|
"""
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec leave_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Member.t()} | {:error, String.t()}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
def leave_group(
|
|
|
|
|
_parent,
|
2020-08-14 09:32:23 +00:00
|
|
|
|
%{group_id: group_id},
|
2020-02-18 07:57:00 +00:00
|
|
|
|
%{
|
|
|
|
|
context: %{
|
2021-09-10 09:35:32 +00:00
|
|
|
|
current_actor: %Actor{} = actor
|
2020-02-18 07:57:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
) do
|
2021-09-10 09:35:32 +00:00
|
|
|
|
with {:group, %Actor{type: :Group} = group} <- {:group, Actors.get_actor(group_id)},
|
2021-09-28 17:40:37 +00:00
|
|
|
|
{:ok, _activity, %Member{} = member} <-
|
|
|
|
|
Actions.Leave.leave(group, actor, true) do
|
2020-08-14 09:32:23 +00:00
|
|
|
|
{:ok, member}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
else
|
|
|
|
|
{:error, :member_not_found} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "Member not found")}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
|
2020-08-14 09:32:23 +00:00
|
|
|
|
{:group, nil} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "Group not found")}
|
2020-08-14 09:32:23 +00:00
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
{:error, :is_not_only_admin} ->
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error,
|
|
|
|
|
dgettext("errors", "You can't leave this group because you are the only administrator")}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def leave_group(_parent, _args, _resolution) do
|
2020-09-29 07:53:48 +00:00
|
|
|
|
{:error, dgettext("errors", "You need to be logged-in to leave a group")}
|
2019-03-01 16:11:28 +00:00
|
|
|
|
end
|
|
|
|
|
|
2021-10-22 09:40:47 +00:00
|
|
|
|
@doc """
|
|
|
|
|
Follow a group
|
|
|
|
|
"""
|
|
|
|
|
@spec follow_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Follower.t()} | {:error, String.t()}
|
|
|
|
|
def follow_group(_parent, %{group_id: group_id, notify: _notify}, %{
|
|
|
|
|
context: %{current_actor: %Actor{} = actor}
|
|
|
|
|
}) do
|
|
|
|
|
case Actors.get_actor(group_id) do
|
|
|
|
|
%Actor{type: :Group} = group ->
|
2021-10-25 11:18:30 +00:00
|
|
|
|
case Actions.Follow.follow(actor, group) do
|
|
|
|
|
{:ok, _activity, %Follower{} = follower} ->
|
|
|
|
|
{:ok, follower}
|
|
|
|
|
|
|
|
|
|
{:error, :already_following} ->
|
|
|
|
|
{:error, dgettext("errors", "You are already following this group")}
|
2021-10-22 09:40:47 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
nil ->
|
|
|
|
|
{:error, dgettext("errors", "Group not found")}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def follow_group(_parent, _args, _resolution) do
|
|
|
|
|
{:error, dgettext("errors", "You need to be logged-in to follow a group")}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
|
Update a group follow
|
|
|
|
|
"""
|
|
|
|
|
@spec update_group_follow(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Member.t()} | {:error, String.t()}
|
|
|
|
|
def update_group_follow(_parent, %{follow_id: follow_id, notify: notify}, %{
|
|
|
|
|
context: %{current_actor: %Actor{} = actor}
|
|
|
|
|
}) do
|
|
|
|
|
case Actors.get_follower(follow_id) do
|
|
|
|
|
%Follower{} = follower ->
|
|
|
|
|
if follower.actor_id == actor.id do
|
|
|
|
|
# Update notify
|
|
|
|
|
Actors.update_follower(follower, %{notify: notify})
|
|
|
|
|
else
|
|
|
|
|
{:error, dgettext("errors", "Follow does not match your account")}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
nil ->
|
|
|
|
|
{:error, dgettext("errors", "Follow not found")}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def update_group_follow(_parent, _args, _resolution) do
|
|
|
|
|
{:error, dgettext("errors", "You need to be logged-in to update a group follow")}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
|
Unfollow a group
|
|
|
|
|
"""
|
|
|
|
|
@spec unfollow_group(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Follower.t()} | {:error, String.t()}
|
|
|
|
|
def unfollow_group(_parent, %{group_id: group_id}, %{
|
|
|
|
|
context: %{current_actor: %Actor{} = actor}
|
|
|
|
|
}) do
|
|
|
|
|
case Actors.get_actor(group_id) do
|
|
|
|
|
%Actor{type: :Group} = group ->
|
|
|
|
|
with {:ok, _activity, %Follower{} = follower} <- Actions.Follow.unfollow(actor, group) do
|
|
|
|
|
{:ok, follower}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
nil ->
|
|
|
|
|
{:error, dgettext("errors", "Group not found")}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def unfollow_group(_parent, _args, _resolution) do
|
|
|
|
|
{:error, dgettext("errors", "You need to be logged-in to unfollow a group")}
|
|
|
|
|
end
|
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec find_events_for_group(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
|
{:ok, Page.t(Event.t())}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
def find_events_for_group(
|
|
|
|
|
%Actor{id: group_id} = group,
|
2020-09-02 15:42:17 +00:00
|
|
|
|
%{
|
|
|
|
|
page: page,
|
|
|
|
|
limit: limit
|
|
|
|
|
} = args,
|
2020-02-18 07:57:00 +00:00
|
|
|
|
%{
|
|
|
|
|
context: %{
|
2021-09-10 09:35:32 +00:00
|
|
|
|
current_user: %User{role: user_role},
|
|
|
|
|
current_actor: %Actor{id: actor_id}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
) do
|
2021-09-10 09:35:32 +00:00
|
|
|
|
if Actors.is_member?(actor_id, group_id) or is_moderator(user_role) do
|
2020-02-18 07:57:00 +00:00
|
|
|
|
# TODO : Handle public / restricted to group members events
|
2020-09-02 15:42:17 +00:00
|
|
|
|
{:ok,
|
|
|
|
|
Events.list_organized_events_for_group(
|
|
|
|
|
group,
|
|
|
|
|
:all,
|
|
|
|
|
Map.get(args, :after_datetime),
|
|
|
|
|
Map.get(args, :before_datetime),
|
|
|
|
|
page,
|
|
|
|
|
limit
|
|
|
|
|
)}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
else
|
2021-09-10 09:35:32 +00:00
|
|
|
|
find_events_for_group(group, args, nil)
|
2020-02-18 07:57:00 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-09-02 15:42:17 +00:00
|
|
|
|
def find_events_for_group(
|
|
|
|
|
%Actor{} = group,
|
|
|
|
|
%{
|
|
|
|
|
page: page,
|
|
|
|
|
limit: limit
|
|
|
|
|
} = args,
|
|
|
|
|
_resolution
|
|
|
|
|
) do
|
|
|
|
|
{:ok,
|
|
|
|
|
Events.list_organized_events_for_group(
|
|
|
|
|
group,
|
|
|
|
|
:public,
|
|
|
|
|
Map.get(args, :after_datetime),
|
|
|
|
|
Map.get(args, :before_datetime),
|
|
|
|
|
page,
|
|
|
|
|
limit
|
|
|
|
|
)}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
end
|
|
|
|
|
|
2021-09-28 17:40:37 +00:00
|
|
|
|
@spec restrict_fields_for_non_member_request(Actor.t()) :: Actor.t()
|
2020-02-18 07:57:00 +00:00
|
|
|
|
defp restrict_fields_for_non_member_request(%Actor{} = group) do
|
2021-09-28 17:40:37 +00:00
|
|
|
|
%Actor{
|
|
|
|
|
group
|
|
|
|
|
| followers: [],
|
2020-02-18 07:57:00 +00:00
|
|
|
|
followings: [],
|
|
|
|
|
organized_events: [],
|
|
|
|
|
comments: [],
|
|
|
|
|
feed_tokens: []
|
2021-09-28 17:40:37 +00:00
|
|
|
|
}
|
2020-02-18 07:57:00 +00:00
|
|
|
|
end
|
2018-12-03 10:58:57 +00:00
|
|
|
|
end
|