2020-01-26 20:34:25 +01:00
|
|
|
defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
2019-01-03 14:59:59 +01:00
|
|
|
@moduledoc """
|
2019-09-22 16:26:23 +02:00
|
|
|
Handles the comment-related GraphQL calls.
|
2019-01-03 14:59:59 +01:00
|
|
|
"""
|
2019-09-13 01:35:03 +02:00
|
|
|
|
2021-09-10 11:35:32 +02:00
|
|
|
alias Mobilizon.{Actors, Admin, Discussions, Events}
|
2020-01-22 02:14:42 +01:00
|
|
|
alias Mobilizon.Actors.Actor
|
2020-07-09 17:24:28 +02:00
|
|
|
alias Mobilizon.Discussions.Comment, as: CommentModel
|
2020-10-05 17:42:53 +02:00
|
|
|
alias Mobilizon.Events.{Event, EventOptions}
|
2023-01-31 19:35:29 +01:00
|
|
|
alias Mobilizon.Service.Akismet
|
2019-09-22 16:26:23 +02:00
|
|
|
alias Mobilizon.Users.User
|
2020-09-29 09:53:48 +02:00
|
|
|
import Mobilizon.Web.Gettext
|
2019-09-22 16:26:23 +02:00
|
|
|
|
2020-01-26 21:11:16 +01:00
|
|
|
alias Mobilizon.GraphQL.API.Comments
|
2018-12-14 17:41:55 +01:00
|
|
|
|
2019-09-13 01:35:03 +02:00
|
|
|
require Logger
|
|
|
|
|
2021-09-28 19:40:37 +02:00
|
|
|
@spec get_thread(any(), map(), Absinthe.Resolution.t()) :: {:ok, [CommentModel.t()]}
|
2019-11-15 18:36:47 +01:00
|
|
|
def get_thread(_parent, %{id: thread_id}, _context) do
|
2020-07-09 17:24:28 +02:00
|
|
|
{:ok, Discussions.get_thread_replies(thread_id)}
|
2019-11-15 18:36:47 +01:00
|
|
|
end
|
|
|
|
|
2021-09-28 19:40:37 +02:00
|
|
|
@spec create_comment(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
{:ok, CommentModel.t()} | {:error, :unauthorized | :not_found | any() | String.t()}
|
2020-01-26 20:34:25 +01:00
|
|
|
def create_comment(
|
|
|
|
_parent,
|
2020-11-19 17:06:28 +01:00
|
|
|
%{event_id: event_id} = args,
|
2020-02-18 08:57:00 +01:00
|
|
|
%{
|
2023-01-31 19:35:29 +01:00
|
|
|
context:
|
|
|
|
%{
|
|
|
|
current_actor: %Actor{id: actor_id, preferred_username: preferred_username},
|
|
|
|
current_user: %User{email: email}
|
|
|
|
} = context
|
2020-02-18 08:57:00 +01:00
|
|
|
}
|
2020-01-26 20:34:25 +01:00
|
|
|
) do
|
2023-01-31 19:35:29 +01:00
|
|
|
current_ip = Map.get(context, :ip)
|
|
|
|
user_agent = Map.get(context, :user_agent, "")
|
|
|
|
|
2021-09-28 19:40:37 +02:00
|
|
|
case Events.get_event(event_id) do
|
|
|
|
{:ok,
|
|
|
|
%Event{
|
|
|
|
options: %EventOptions{comment_moderation: comment_moderation},
|
|
|
|
organizer_actor_id: organizer_actor_id
|
|
|
|
}} ->
|
|
|
|
if comment_moderation != :closed || actor_id == organizer_actor_id do
|
|
|
|
args = Map.put(args, :actor_id, actor_id)
|
|
|
|
|
2023-01-31 19:35:29 +01:00
|
|
|
if Akismet.check_comment(
|
|
|
|
args.text,
|
|
|
|
preferred_username,
|
|
|
|
!is_nil(Map.get(args, :in_reply_to_comment_id)),
|
|
|
|
email,
|
|
|
|
current_ip,
|
|
|
|
user_agent
|
|
|
|
) do
|
|
|
|
case Comments.create_comment(args) do
|
|
|
|
{:ok, _, %CommentModel{} = comment} ->
|
|
|
|
{:ok, comment}
|
2021-09-28 19:40:37 +02:00
|
|
|
|
2023-01-31 19:35:29 +01:00
|
|
|
{:error, err} ->
|
|
|
|
{:error, err}
|
|
|
|
end
|
|
|
|
else
|
|
|
|
{:error,
|
|
|
|
dgettext(
|
|
|
|
"errors",
|
|
|
|
"This comment was detected as spam."
|
|
|
|
)}
|
2021-09-28 19:40:37 +02:00
|
|
|
end
|
|
|
|
else
|
|
|
|
{:error, :unauthorized}
|
|
|
|
end
|
2021-03-25 12:11:49 +01:00
|
|
|
|
2021-09-28 19:40:37 +02:00
|
|
|
{:error, :event_not_found} ->
|
|
|
|
{:error, :not_found}
|
2018-12-14 17:41:55 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-11-15 18:36:47 +01:00
|
|
|
def create_comment(_parent, _args, _context) do
|
2020-09-29 09:53:48 +02:00
|
|
|
{:error, dgettext("errors", "You are not allowed to create a comment if not connected")}
|
2018-12-14 17:41:55 +01:00
|
|
|
end
|
2019-11-15 18:36:47 +01:00
|
|
|
|
2021-09-28 19:40:37 +02:00
|
|
|
@spec update_comment(any(), map(), Absinthe.Resolution.t()) ::
|
|
|
|
{:ok, CommentModel.t()} | {:error, :unauthorized | :not_found | any() | String.t()}
|
2020-02-18 08:57:00 +01:00
|
|
|
def update_comment(
|
|
|
|
_parent,
|
|
|
|
%{text: text, comment_id: comment_id},
|
|
|
|
%{
|
|
|
|
context: %{
|
2021-09-10 11:35:32 +02:00
|
|
|
current_actor: %Actor{id: actor_id}
|
2020-02-18 08:57:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
) do
|
2021-09-28 19:40:37 +02:00
|
|
|
case Mobilizon.Discussions.get_comment_with_preload(comment_id) do
|
|
|
|
%CommentModel{actor_id: comment_actor_id} = comment ->
|
|
|
|
if actor_id == comment_actor_id do
|
|
|
|
case Comments.update_comment(comment, %{text: text}) do
|
|
|
|
{:ok, _, %CommentModel{} = comment} ->
|
|
|
|
{:ok, comment}
|
|
|
|
|
|
|
|
{:error, err} ->
|
|
|
|
{:error, err}
|
|
|
|
end
|
|
|
|
else
|
|
|
|
{:error, dgettext("errors", "You are not the comment creator")}
|
|
|
|
end
|
|
|
|
|
|
|
|
nil ->
|
|
|
|
{:error, :not_found}
|
2020-02-18 08:57:00 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-10-05 15:29:06 +02:00
|
|
|
def update_comment(_parent, _args, _context) do
|
2020-09-29 09:53:48 +02:00
|
|
|
{:error, dgettext("errors", "You are not allowed to update a comment if not connected")}
|
2020-02-18 08:57:00 +01:00
|
|
|
end
|
|
|
|
|
2020-01-26 20:34:25 +01:00
|
|
|
def delete_comment(
|
|
|
|
_parent,
|
2020-08-14 11:32:23 +02:00
|
|
|
%{comment_id: comment_id},
|
2020-02-18 08:57:00 +01:00
|
|
|
%{
|
|
|
|
context: %{
|
2021-09-10 11:35:32 +02:00
|
|
|
current_user: %User{role: role},
|
|
|
|
current_actor: %Actor{id: actor_id} = actor
|
2020-02-18 08:57:00 +01:00
|
|
|
}
|
|
|
|
}
|
2020-01-26 20:34:25 +01:00
|
|
|
) do
|
2021-09-10 11:35:32 +02:00
|
|
|
case Discussions.get_comment_with_preload(comment_id) do
|
|
|
|
%CommentModel{deleted_at: nil} = comment ->
|
|
|
|
cond do
|
2021-10-05 17:43:45 +02:00
|
|
|
{:comment_can_be_managed, true} ==
|
|
|
|
{:comment_can_be_managed, CommentModel.can_be_managed_by?(comment, actor_id)} ->
|
2021-09-10 11:35:32 +02:00
|
|
|
do_delete_comment(comment, actor)
|
|
|
|
|
|
|
|
role in [:moderator, :administrator] ->
|
|
|
|
with {:ok, res} <- do_delete_comment(comment, actor),
|
|
|
|
%Actor{} = actor <- Actors.get_actor(actor_id) do
|
|
|
|
Admin.log_action(actor, "delete", comment)
|
|
|
|
|
|
|
|
{:ok, res}
|
|
|
|
end
|
|
|
|
|
|
|
|
true ->
|
|
|
|
{:error, dgettext("errors", "You cannot delete this comment")}
|
|
|
|
end
|
|
|
|
|
2020-06-15 16:20:58 +02:00
|
|
|
%CommentModel{deleted_at: deleted_at} when not is_nil(deleted_at) ->
|
2020-09-29 09:53:48 +02:00
|
|
|
{:error, dgettext("errors", "Comment is already deleted")}
|
2021-09-10 11:35:32 +02:00
|
|
|
|
|
|
|
nil ->
|
|
|
|
{:error, dgettext("errors", "Comment not found")}
|
2019-11-15 18:36:47 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def delete_comment(_parent, _args, %{}) do
|
2020-09-29 09:53:48 +02:00
|
|
|
{:error, dgettext("errors", "You are not allowed to delete a comment if not connected")}
|
2019-11-15 18:36:47 +01:00
|
|
|
end
|
|
|
|
|
2021-09-28 19:40:37 +02:00
|
|
|
@spec do_delete_comment(CommentModel.t(), Actor.t()) ::
|
|
|
|
{:ok, CommentModel.t()} | {:error, any()}
|
2020-07-09 17:24:28 +02:00
|
|
|
defp do_delete_comment(%CommentModel{} = comment, %Actor{} = actor) do
|
2021-09-28 19:40:37 +02:00
|
|
|
case Comments.delete_comment(comment, actor) do
|
|
|
|
{:ok, _, %CommentModel{} = comment} ->
|
|
|
|
{:ok, comment}
|
|
|
|
|
|
|
|
{:error, err} ->
|
|
|
|
{:error, err}
|
2019-11-15 18:36:47 +01:00
|
|
|
end
|
|
|
|
end
|
2018-12-14 17:41:55 +01:00
|
|
|
end
|