Refactor Mobilizon.Federation.ActivityPub and add typespecs
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -5,8 +5,7 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Activity
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Activity}
|
||||
alias Mobilizon.GraphQL.API.Utils
|
||||
|
||||
@doc """
|
||||
@@ -15,7 +14,7 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
@spec create_comment(map) :: {:ok, Activity.t(), Comment.t()} | any
|
||||
def create_comment(args) do
|
||||
args = extract_pictures_from_comment_body(args)
|
||||
ActivityPub.create(:comment, args, true)
|
||||
Actions.Create.create(:comment, args, true)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@@ -24,7 +23,7 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
@spec update_comment(Comment.t(), map()) :: {:ok, Activity.t(), Comment.t()} | any
|
||||
def update_comment(%Comment{} = comment, args) do
|
||||
args = extract_pictures_from_comment_body(args)
|
||||
ActivityPub.update(comment, args, true)
|
||||
Actions.Update.update(comment, args, true)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@@ -32,7 +31,7 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
"""
|
||||
@spec delete_comment(Comment.t(), Actor.t()) :: {:ok, Activity.t(), Comment.t()} | any
|
||||
def delete_comment(%Comment{} = comment, %Actor{} = actor) do
|
||||
ActivityPub.delete(comment, actor, true)
|
||||
Actions.Delete.delete(comment, actor, true)
|
||||
end
|
||||
|
||||
@doc """
|
||||
@@ -42,7 +41,7 @@ defmodule Mobilizon.GraphQL.API.Comments do
|
||||
def create_discussion(args) do
|
||||
args = extract_pictures_from_comment_body(args)
|
||||
|
||||
ActivityPub.create(
|
||||
Actions.Create.create(
|
||||
:discussion,
|
||||
args,
|
||||
true
|
||||
|
||||
@@ -6,8 +6,7 @@ defmodule Mobilizon.GraphQL.API.Events do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Events.Event
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.{Activity, Utils}
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Activity, Utils}
|
||||
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
|
||||
|
||||
@doc """
|
||||
@@ -16,7 +15,7 @@ defmodule Mobilizon.GraphQL.API.Events do
|
||||
@spec create_event(map) :: {:ok, Activity.t(), Event.t()} | any
|
||||
def create_event(args) do
|
||||
# For now we don't federate drafts but it will be needed if we want to edit them as groups
|
||||
ActivityPub.create(:event, prepare_args(args), should_federate(args))
|
||||
Actions.Create.create(:event, prepare_args(args), should_federate(args))
|
||||
end
|
||||
|
||||
@doc """
|
||||
@@ -24,7 +23,7 @@ defmodule Mobilizon.GraphQL.API.Events do
|
||||
"""
|
||||
@spec update_event(map, Event.t()) :: {:ok, Activity.t(), Event.t()} | any
|
||||
def update_event(args, %Event{} = event) do
|
||||
ActivityPub.update(event, prepare_args(args), should_federate(args))
|
||||
Actions.Update.update(event, prepare_args(args), should_federate(args))
|
||||
end
|
||||
|
||||
@doc """
|
||||
@@ -32,7 +31,7 @@ defmodule Mobilizon.GraphQL.API.Events do
|
||||
"""
|
||||
@spec delete_event(Event.t(), Actor.t(), boolean()) :: {:ok, Activity.t(), Entity.t()} | any()
|
||||
def delete_event(%Event{} = event, %Actor{} = actor, federate \\ true) do
|
||||
ActivityPub.delete(event, actor, federate)
|
||||
Actions.Delete.delete(event, actor, federate)
|
||||
end
|
||||
|
||||
@spec prepare_args(map) :: map
|
||||
|
||||
@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.API.Follows do
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Activity}
|
||||
|
||||
require Logger
|
||||
|
||||
@@ -14,27 +14,27 @@ defmodule Mobilizon.GraphQL.API.Follows do
|
||||
Make an actor (`follower`) follow another (`followed`).
|
||||
"""
|
||||
@spec follow(follower :: Actor.t(), followed :: Actor.t()) ::
|
||||
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
| {:error, String.t()}
|
||||
def follow(%Actor{} = follower, %Actor{} = followed) do
|
||||
ActivityPub.follow(follower, followed)
|
||||
Actions.Follow.follow(follower, followed)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Make an actor (`follower`) unfollow another (`followed`).
|
||||
"""
|
||||
@spec unfollow(follower :: Actor.t(), followed :: Actor.t()) ::
|
||||
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
| {:error, String.t()}
|
||||
def unfollow(%Actor{} = follower, %Actor{} = followed) do
|
||||
ActivityPub.unfollow(follower, followed)
|
||||
Actions.Follow.unfollow(follower, followed)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Make an actor (`followed`) accept the follow from another (`follower`).
|
||||
"""
|
||||
@spec accept(follower :: Actor.t(), followed :: Actor.t()) ::
|
||||
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
| {:error, String.t()}
|
||||
def accept(%Actor{url: follower_url} = follower, %Actor{url: followed_url} = followed) do
|
||||
Logger.debug(
|
||||
@@ -43,7 +43,7 @@ defmodule Mobilizon.GraphQL.API.Follows do
|
||||
|
||||
case Actors.is_following(follower, followed) do
|
||||
%Follower{approved: false} = follow ->
|
||||
ActivityPub.accept(
|
||||
Actions.Accept.accept(
|
||||
:follow,
|
||||
follow,
|
||||
true
|
||||
@@ -61,7 +61,7 @@ defmodule Mobilizon.GraphQL.API.Follows do
|
||||
Make an actor (`followed`) reject the follow from another (`follower`).
|
||||
"""
|
||||
@spec reject(follower :: Actor.t(), followed :: Actor.t()) ::
|
||||
{:ok, Mobilizon.Federation.ActivityPub.Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
{:ok, Activity.t(), Mobilizon.Actors.Follower.t()}
|
||||
| {:error, String.t()}
|
||||
def reject(%Actor{url: follower_url} = follower, %Actor{url: followed_url} = followed) do
|
||||
Logger.debug(
|
||||
@@ -73,7 +73,7 @@ defmodule Mobilizon.GraphQL.API.Follows do
|
||||
{:error, "Follow already accepted"}
|
||||
|
||||
%Follower{} = follow ->
|
||||
ActivityPub.reject(
|
||||
Actions.Reject.reject(
|
||||
:follow,
|
||||
follow,
|
||||
true
|
||||
|
||||
@@ -6,39 +6,35 @@ defmodule Mobilizon.GraphQL.API.Groups do
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Activity
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Activity}
|
||||
alias Mobilizon.Service.Formatter.HTML
|
||||
|
||||
@doc """
|
||||
Create a group
|
||||
"""
|
||||
@spec create_group(map) :: {:ok, Activity.t(), Actor.t()} | any
|
||||
@spec create_group(map) ::
|
||||
{:ok, Activity.t(), Actor.t()}
|
||||
| {:error, String.t() | Ecto.Changeset.t()}
|
||||
def create_group(args) do
|
||||
with preferred_username <-
|
||||
args |> Map.get(:preferred_username) |> HTML.strip_tags() |> String.trim(),
|
||||
{:existing_group, nil} <-
|
||||
{:existing_group, Actors.get_local_actor_by_name(preferred_username)},
|
||||
args <- args |> Map.put(:type, :Group),
|
||||
{:ok, %Activity{} = activity, %Actor{} = group} <-
|
||||
ActivityPub.create(:actor, args, true, %{"actor" => args.creator_actor.url}) do
|
||||
{:ok, activity, group}
|
||||
else
|
||||
{:existing_group, _} ->
|
||||
{:error, "A group with this name already exists"}
|
||||
preferred_username =
|
||||
args |> Map.get(:preferred_username) |> HTML.strip_tags() |> String.trim()
|
||||
|
||||
args = args |> Map.put(:type, :Group)
|
||||
|
||||
case Actors.get_local_actor_by_name(preferred_username) do
|
||||
nil ->
|
||||
Actions.Create.create(:actor, args, true, %{"actor" => args.creator_actor.url})
|
||||
|
||||
%Actor{} ->
|
||||
{:error, "A profile or group with that name already exists"}
|
||||
end
|
||||
end
|
||||
|
||||
@spec create_group(map) :: {:ok, Activity.t(), Actor.t()} | any
|
||||
@spec update_group(map) ::
|
||||
{:ok, Activity.t(), Actor.t()} | {:error, :group_not_found | Ecto.Changeset.t()}
|
||||
def update_group(%{id: id} = args) do
|
||||
with {:existing_group, {:ok, %Actor{type: :Group} = group}} <-
|
||||
{:existing_group, Actors.get_group_by_actor_id(id)},
|
||||
{:ok, %Activity{} = activity, %Actor{} = group} <-
|
||||
ActivityPub.update(group, args, true, %{"actor" => args.updater_actor.url}) do
|
||||
{:ok, activity, group}
|
||||
else
|
||||
{:existing_group, _} ->
|
||||
{:error, "A group with this name already exists"}
|
||||
with {:ok, %Actor{type: :Group} = group} <- Actors.get_group_by_actor_id(id) do
|
||||
Actions.Update.update(group, args, true, %{"actor" => args.updater_actor.url})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,8 +6,7 @@ defmodule Mobilizon.GraphQL.API.Participations do
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Events
|
||||
alias Mobilizon.Events.{Event, Participant}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Activity
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Activity}
|
||||
alias Mobilizon.Service.Notifications.Scheduler
|
||||
alias Mobilizon.Web.Email.Participation
|
||||
|
||||
@@ -19,7 +18,7 @@ defmodule Mobilizon.GraphQL.API.Participations do
|
||||
{:error, :already_participant}
|
||||
|
||||
{:error, :participant_not_found} ->
|
||||
ActivityPub.join(event, actor, Map.get(args, :local, true), %{metadata: args})
|
||||
Actions.Join.join(event, actor, Map.get(args, :local, true), %{metadata: args})
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,7 +26,7 @@ defmodule Mobilizon.GraphQL.API.Participations do
|
||||
{:ok, Activity.t(), Participant.t()}
|
||||
| {:error, :is_only_organizer | :participant_not_found | Ecto.Changeset.t()}
|
||||
def leave(%Event{} = event, %Actor{} = actor, args \\ %{}),
|
||||
do: ActivityPub.leave(event, actor, Map.get(args, :local, true), %{metadata: args})
|
||||
do: Actions.Leave.leave(event, actor, Map.get(args, :local, true), %{metadata: args})
|
||||
|
||||
@doc """
|
||||
Update participation status
|
||||
@@ -52,15 +51,18 @@ defmodule Mobilizon.GraphQL.API.Participations do
|
||||
%Participant{} = participation,
|
||||
%Actor{} = moderator
|
||||
) do
|
||||
with {:ok, activity, %Participant{role: :participant} = participation} <-
|
||||
ActivityPub.accept(
|
||||
:join,
|
||||
participation,
|
||||
true,
|
||||
%{"actor" => moderator.url}
|
||||
),
|
||||
:ok <- Participation.send_emails_to_local_user(participation) do
|
||||
{:ok, activity, participation}
|
||||
case Actions.Accept.accept(
|
||||
:join,
|
||||
participation,
|
||||
true,
|
||||
%{"actor" => moderator.url}
|
||||
) do
|
||||
{:ok, activity, %Participant{role: :participant} = participation} ->
|
||||
Participation.send_emails_to_local_user(participation)
|
||||
{:ok, activity, participation}
|
||||
|
||||
{:error, err} ->
|
||||
{:error, err}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -70,7 +72,7 @@ defmodule Mobilizon.GraphQL.API.Participations do
|
||||
%Actor{} = moderator
|
||||
) do
|
||||
with {:ok, activity, %Participant{role: :rejected} = participation} <-
|
||||
ActivityPub.reject(
|
||||
Actions.Reject.reject(
|
||||
:join,
|
||||
participation,
|
||||
true,
|
||||
|
||||
@@ -9,36 +9,29 @@ defmodule Mobilizon.GraphQL.API.Reports do
|
||||
alias Mobilizon.Reports.{Note, Report, ReportStatus}
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Activity
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Activity}
|
||||
|
||||
@doc """
|
||||
Create a report/flag on an actor, and optionally on an event or on comments.
|
||||
"""
|
||||
@spec report(map()) :: {:ok, Activity.t(), Report.t()} | {:error, any()}
|
||||
@spec report(map()) :: {:ok, Activity.t(), Report.t()} | {:error, Ecto.Changeset.t()}
|
||||
def report(args) do
|
||||
case ActivityPub.flag(args, Map.get(args, :forward, false) == true) do
|
||||
{:ok, %Activity{} = activity, %Report{} = report} ->
|
||||
{:ok, activity, report}
|
||||
|
||||
err ->
|
||||
{:error, err}
|
||||
end
|
||||
Actions.Flag.flag(args, Map.get(args, :forward, false) == true)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Update the state of a report
|
||||
"""
|
||||
@spec update_report_status(Actor.t(), Report.t(), ReportStatus.t()) ::
|
||||
{:ok, Report.t()} | {:error, String.t()}
|
||||
{:ok, Report.t()} | {:error, Ecto.Changeset.t() | String.t()}
|
||||
def update_report_status(%Actor{} = actor, %Report{} = report, state) do
|
||||
with {:valid_state, true} <-
|
||||
{:valid_state, ReportStatus.valid_value?(state)},
|
||||
{:ok, %Report{} = report} <- ReportsAction.update_report(report, %{"status" => state}),
|
||||
{:ok, _} <- Admin.log_action(actor, "update", report) do
|
||||
{:ok, report}
|
||||
if ReportStatus.valid_value?(state) do
|
||||
with {:ok, %Report{} = report} <- ReportsAction.update_report(report, %{"status" => state}) do
|
||||
Admin.log_action(actor, "update", report)
|
||||
{:ok, report}
|
||||
end
|
||||
else
|
||||
{:valid_state, false} -> {:error, "Unsupported state"}
|
||||
{:error, "Unsupported state"}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -46,49 +39,52 @@ defmodule Mobilizon.GraphQL.API.Reports do
|
||||
Create a note on a report
|
||||
"""
|
||||
@spec create_report_note(Report.t(), Actor.t(), String.t()) ::
|
||||
{:ok, Note.t()} | {:error, String.t()}
|
||||
{:ok, Note.t()} | {:error, String.t() | Ecto.Changeset.t()}
|
||||
def create_report_note(
|
||||
%Report{id: report_id},
|
||||
%Actor{id: moderator_id, user_id: user_id} = moderator,
|
||||
content
|
||||
) do
|
||||
with %User{role: role} <- Users.get_user!(user_id),
|
||||
{:role, true} <- {:role, role in [:administrator, :moderator]},
|
||||
{:ok, %Note{} = note} <-
|
||||
Mobilizon.Reports.create_note(%{
|
||||
"report_id" => report_id,
|
||||
"moderator_id" => moderator_id,
|
||||
"content" => content
|
||||
}),
|
||||
{:ok, _} <- Admin.log_action(moderator, "create", note) do
|
||||
{:ok, note}
|
||||
%User{role: role} = Users.get_user!(user_id)
|
||||
|
||||
if role in [:administrator, :moderator] do
|
||||
with {:ok, %Note{} = note} <-
|
||||
Mobilizon.Reports.create_note(%{
|
||||
"report_id" => report_id,
|
||||
"moderator_id" => moderator_id,
|
||||
"content" => content
|
||||
}),
|
||||
{:ok, _} <- Admin.log_action(moderator, "create", note) do
|
||||
{:ok, note}
|
||||
end
|
||||
else
|
||||
{:role, false} ->
|
||||
{:error, "You need to be a moderator or an administrator to create a note on a report"}
|
||||
{:error, "You need to be a moderator or an administrator to create a note on a report"}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Delete a report note
|
||||
"""
|
||||
@spec delete_report_note(Note.t(), Actor.t()) :: {:ok, Note.t()} | {:error, String.t()}
|
||||
@spec delete_report_note(Note.t(), Actor.t()) ::
|
||||
{:ok, Note.t()} | {:error, Ecto.Changeset.t() | String.t()}
|
||||
def delete_report_note(
|
||||
%Note{moderator_id: note_moderator_id} = note,
|
||||
%Actor{id: moderator_id, user_id: user_id} = moderator
|
||||
) do
|
||||
with {:same_actor, true} <- {:same_actor, note_moderator_id == moderator_id},
|
||||
%User{role: role} <- Users.get_user!(user_id),
|
||||
{:role, true} <- {:role, role in [:administrator, :moderator]},
|
||||
{:ok, %Note{} = note} <-
|
||||
Mobilizon.Reports.delete_note(note),
|
||||
{:ok, _} <- Admin.log_action(moderator, "delete", note) do
|
||||
{:ok, note}
|
||||
else
|
||||
{:role, false} ->
|
||||
{:error, "You need to be a moderator or an administrator to create a note on a report"}
|
||||
if note_moderator_id == moderator_id do
|
||||
%User{role: role} = Users.get_user!(user_id)
|
||||
|
||||
{:same_actor, false} ->
|
||||
{:error, "You can only remove your own notes"}
|
||||
if role in [:administrator, :moderator] do
|
||||
with {:ok, %Note{} = note} <-
|
||||
Mobilizon.Reports.delete_note(note),
|
||||
{:ok, _} <- Admin.log_action(moderator, "delete", note) do
|
||||
{:ok, note}
|
||||
end
|
||||
else
|
||||
{:error, "You need to be a moderator or an administrator to create a note on a report"}
|
||||
end
|
||||
else
|
||||
{:error, "You can only remove your own notes"}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
|
||||
|
||||
import Mobilizon.Users.Guards
|
||||
alias Mobilizon.{Activities, Actors}
|
||||
alias Mobilizon.Activities.Activity
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Service.Activity.Utils
|
||||
alias Mobilizon.Storage.Page
|
||||
@@ -12,6 +13,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
|
||||
|
||||
require Logger
|
||||
|
||||
@spec group_activity(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Activity.t())} | {:error, :unauthorized | :unauthenticated}
|
||||
def group_activity(%Actor{type: :Group, id: group_id}, %{page: page, limit: limit} = args, %{
|
||||
context: %{current_user: %User{role: role}, current_actor: %Actor{id: actor_id}}
|
||||
}) do
|
||||
|
||||
@@ -6,13 +6,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
|
||||
import Mobilizon.Users.Guards
|
||||
alias Mobilizon.{Actors, Admin}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.Service.Workers.Background
|
||||
alias Mobilizon.Users.User
|
||||
import Mobilizon.Web.Gettext, only: [dgettext: 2]
|
||||
|
||||
require Logger
|
||||
|
||||
@spec refresh_profile(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t()}
|
||||
def refresh_profile(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
|
||||
when is_admin(role) do
|
||||
case Actors.get_actor(id) do
|
||||
@@ -31,6 +33,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
|
||||
end
|
||||
end
|
||||
|
||||
@spec suspend_profile(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t()}
|
||||
def suspend_profile(_parent, %{id: id}, %{
|
||||
context: %{
|
||||
current_user: %User{role: role},
|
||||
@@ -39,28 +43,28 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
|
||||
})
|
||||
when is_moderator(role) do
|
||||
case Actors.get_actor_with_preload(id) do
|
||||
%Actor{suspended: false} = actor ->
|
||||
case actor do
|
||||
# Suspend a group on this instance
|
||||
%Actor{type: :Group, domain: nil} ->
|
||||
Logger.debug("We're suspending a group on this very instance")
|
||||
ActivityPub.delete(actor, moderator_actor, true, %{suspension: true})
|
||||
Admin.log_action(moderator_actor, "suspend", actor)
|
||||
{:ok, actor}
|
||||
# Suspend a group on this instance
|
||||
%Actor{suspended: false, type: :Group, domain: nil} = actor ->
|
||||
Logger.debug("We're suspending a group on this very instance")
|
||||
Actions.Delete.delete(actor, moderator_actor, true, %{suspension: true})
|
||||
Admin.log_action(moderator_actor, "suspend", actor)
|
||||
{:ok, actor}
|
||||
|
||||
# Delete a remote actor
|
||||
%Actor{domain: domain} when not is_nil(domain) ->
|
||||
Logger.debug("We're just deleting a remote instance")
|
||||
Actors.delete_actor(actor, suspension: true)
|
||||
Admin.log_action(moderator_actor, "suspend", actor)
|
||||
{:ok, actor}
|
||||
# Delete a remote actor
|
||||
%Actor{suspended: false, domain: domain} = actor when not is_nil(domain) ->
|
||||
Logger.debug("We're just deleting a remote instance")
|
||||
Actors.delete_actor(actor, suspension: true)
|
||||
Admin.log_action(moderator_actor, "suspend", actor)
|
||||
{:ok, actor}
|
||||
|
||||
%Actor{domain: nil} ->
|
||||
{:error, dgettext("errors", "No remote profile found with this ID")}
|
||||
end
|
||||
%Actor{suspended: false, domain: nil} ->
|
||||
{:error, dgettext("errors", "No remote profile found with this ID")}
|
||||
|
||||
%Actor{suspended: true} ->
|
||||
{:error, dgettext("errors", "Profile already suspended")}
|
||||
|
||||
nil ->
|
||||
{:error, dgettext("errors", "Profile not found")}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -68,6 +72,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
|
||||
{:error, dgettext("errors", "Only moderators and administrators can suspend a profile")}
|
||||
end
|
||||
|
||||
@spec unsuspend_profile(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t()}
|
||||
def unsuspend_profile(_parent, %{id: id}, %{
|
||||
context: %{
|
||||
current_user: %User{role: role},
|
||||
|
||||
@@ -6,14 +6,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
import Mobilizon.Users.Guards
|
||||
|
||||
alias Mobilizon.{Actors, Admin, Config, Events}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
alias Mobilizon.Admin.{ActionLog, Setting}
|
||||
alias Mobilizon.Cldr.Language
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Relay}
|
||||
alias Mobilizon.Reports.{Note, Report}
|
||||
alias Mobilizon.Service.Statistics
|
||||
alias Mobilizon.Storage.Page
|
||||
@@ -21,6 +20,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
import Mobilizon.Web.Gettext
|
||||
require Logger
|
||||
|
||||
@spec list_action_logs(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(ActionLog.t())} | {:error, String.t()}
|
||||
def list_action_logs(
|
||||
_parent,
|
||||
%{page: page, limit: limit},
|
||||
@@ -38,10 +39,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
id: id,
|
||||
inserted_at: inserted_at
|
||||
} = action_log ->
|
||||
with data when is_map(data) <-
|
||||
transform_action_log(String.to_existing_atom(target_type), action, action_log) do
|
||||
Map.merge(data, %{actor: actor, id: id, inserted_at: inserted_at})
|
||||
end
|
||||
target_type
|
||||
|> String.to_existing_atom()
|
||||
|> transform_action_log(action, action_log)
|
||||
|> Map.merge(%{actor: actor, id: id, inserted_at: inserted_at})
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
@@ -53,6 +54,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
{:error, dgettext("errors", "You need to be logged-in and a moderator to list action logs")}
|
||||
end
|
||||
|
||||
@spec transform_action_log(module(), atom(), ActionLog.t()) :: map()
|
||||
defp transform_action_log(
|
||||
Report,
|
||||
:update,
|
||||
@@ -123,6 +125,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
|
||||
# Changes are stored as %{"key" => "value"} so we need to convert them back as struct
|
||||
@spec convert_changes_to_struct(module(), map()) :: struct()
|
||||
defp convert_changes_to_struct(struct, %{"report_id" => _report_id} = changes) do
|
||||
with data <- for({key, val} <- changes, into: %{}, do: {String.to_existing_atom(key), val}),
|
||||
data <- Map.put(data, :report, Mobilizon.Reports.get_report(data.report_id)) do
|
||||
@@ -143,6 +146,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
|
||||
# datetimes are not unserialized as DateTime/NaiveDateTime so we do it manually with changeset data
|
||||
@spec process_eventual_type(Ecto.Changeset.t(), String.t(), String.t() | nil) ::
|
||||
DateTime.t() | NaiveDateTime.t() | any()
|
||||
defp process_eventual_type(changeset, key, val) do
|
||||
cond do
|
||||
changeset[String.to_existing_atom(key)] == :utc_datetime and not is_nil(val) ->
|
||||
@@ -158,6 +163,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_list_of_languages(any(), any(), any()) :: {:ok, String.t()} | {:error, any()}
|
||||
def get_list_of_languages(_parent, %{codes: codes}, _resolution) when is_list(codes) do
|
||||
locale = Gettext.get_locale()
|
||||
locale = if Cldr.known_locale_name?(locale), do: locale, else: "en"
|
||||
@@ -187,6 +193,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_dashboard(any(), any(), Absinthe.Resolution.t()) ::
|
||||
{:ok, map()} | {:error, String.t()}
|
||||
def get_dashboard(_parent, _args, %{context: %{current_user: %User{role: role}}})
|
||||
when is_admin(role) do
|
||||
last_public_event_published =
|
||||
@@ -225,6 +233,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
)}
|
||||
end
|
||||
|
||||
@spec get_settings(any(), any(), Absinthe.Resolution.t()) :: {:ok, map()} | {:error, String.t()}
|
||||
def get_settings(_parent, _args, %{
|
||||
context: %{current_user: %User{role: role}}
|
||||
})
|
||||
@@ -237,6 +246,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
dgettext("errors", "You need to be logged-in and an administrator to access admin settings")}
|
||||
end
|
||||
|
||||
@spec save_settings(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, map()} | {:error, String.t()}
|
||||
def save_settings(_parent, args, %{
|
||||
context: %{current_user: %User{role: role}}
|
||||
})
|
||||
@@ -261,6 +272,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
dgettext("errors", "You need to be logged-in and an administrator to save admin settings")}
|
||||
end
|
||||
|
||||
@spec list_relay_followers(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Follower.t())} | {:error, :unauthorized | :unauthenticated}
|
||||
def list_relay_followers(
|
||||
_parent,
|
||||
%{page: page, limit: limit},
|
||||
@@ -283,6 +296,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
{:error, :unauthenticated}
|
||||
end
|
||||
|
||||
@spec list_relay_followings(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Follower.t())} | {:error, :unauthorized | :unauthenticated}
|
||||
def list_relay_followings(
|
||||
_parent,
|
||||
%{page: page, limit: limit},
|
||||
@@ -305,6 +320,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
{:error, :unauthenticated}
|
||||
end
|
||||
|
||||
@spec create_relay(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Follower.t()} | {:error, any()}
|
||||
def create_relay(_parent, %{address: address}, %{context: %{current_user: %User{role: role}}})
|
||||
when is_admin(role) do
|
||||
case Relay.follow(address) do
|
||||
@@ -316,6 +333,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
end
|
||||
|
||||
@spec remove_relay(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Follower.t()} | {:error, any()}
|
||||
def remove_relay(_parent, %{address: address}, %{context: %{current_user: %User{role: role}}})
|
||||
when is_admin(role) do
|
||||
case Relay.unfollow(address) do
|
||||
@@ -327,6 +346,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
end
|
||||
|
||||
@spec accept_subscription(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Follower.t()} | {:error, any()}
|
||||
def accept_subscription(
|
||||
_parent,
|
||||
%{address: address},
|
||||
@@ -342,6 +363,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
end
|
||||
|
||||
@spec reject_subscription(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Follower.t()} | {:error, any()}
|
||||
def reject_subscription(
|
||||
_parent,
|
||||
%{address: address},
|
||||
@@ -357,7 +380,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
end
|
||||
end
|
||||
|
||||
@spec eventually_update_instance_actor(map()) :: :ok
|
||||
@spec eventually_update_instance_actor(map()) :: :ok | {:error, :instance_actor_update_failure}
|
||||
defp eventually_update_instance_actor(admin_setting_args) do
|
||||
args = %{}
|
||||
new_instance_description = Map.get(admin_setting_args, :instance_description)
|
||||
@@ -382,7 +405,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
||||
if args != %{} do
|
||||
%Actor{} = instance_actor = Relay.get_actor()
|
||||
|
||||
case ActivityPub.update(instance_actor, args, true) do
|
||||
case Actions.Update.update(instance_actor, args, true) do
|
||||
{:ok, _activity, _actor} ->
|
||||
:ok
|
||||
|
||||
|
||||
@@ -14,10 +14,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
|
||||
require Logger
|
||||
|
||||
@spec get_thread(any(), map(), Absinthe.Resolution.t()) :: {:ok, [CommentModel.t()]}
|
||||
def get_thread(_parent, %{id: thread_id}, _context) do
|
||||
{:ok, Discussions.get_thread_replies(thread_id)}
|
||||
end
|
||||
|
||||
@spec create_comment(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, CommentModel.t()} | {:error, :unauthorized | :not_found | any() | String.t()}
|
||||
def create_comment(
|
||||
_parent,
|
||||
%{event_id: event_id} = args,
|
||||
@@ -27,25 +30,28 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:find_event,
|
||||
{:ok,
|
||||
%Event{
|
||||
options: %EventOptions{comment_moderation: comment_moderation},
|
||||
organizer_actor_id: organizer_actor_id
|
||||
}}} <-
|
||||
{:find_event, Events.get_event(event_id)},
|
||||
{:allowed, true} <-
|
||||
{:allowed, comment_moderation != :closed || actor_id == organizer_actor_id},
|
||||
args <- Map.put(args, :actor_id, actor_id),
|
||||
{:ok, _, %CommentModel{} = comment} <-
|
||||
Comments.create_comment(args) do
|
||||
{:ok, comment}
|
||||
else
|
||||
{:error, err} ->
|
||||
{:error, err}
|
||||
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)
|
||||
|
||||
{:allowed, false} ->
|
||||
{:error, :unauthorized}
|
||||
case Comments.create_comment(args) do
|
||||
{:ok, _, %CommentModel{} = comment} ->
|
||||
{:ok, comment}
|
||||
|
||||
{:error, err} ->
|
||||
{:error, err}
|
||||
end
|
||||
else
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
|
||||
{:error, :event_not_found} ->
|
||||
{:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,6 +59,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
{:error, dgettext("errors", "You are not allowed to create a comment if not connected")}
|
||||
end
|
||||
|
||||
@spec update_comment(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, CommentModel.t()} | {:error, :unauthorized | :not_found | any() | String.t()}
|
||||
def update_comment(
|
||||
_parent,
|
||||
%{text: text, comment_id: comment_id},
|
||||
@@ -62,11 +70,22 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
}
|
||||
}
|
||||
) do
|
||||
with %CommentModel{actor_id: comment_actor_id} = comment <-
|
||||
Mobilizon.Discussions.get_comment_with_preload(comment_id),
|
||||
true <- actor_id == comment_actor_id,
|
||||
{:ok, _, %CommentModel{} = comment} <- Comments.update_comment(comment, %{text: text}) do
|
||||
{:ok, comment}
|
||||
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}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -114,10 +133,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
|
||||
{:error, dgettext("errors", "You are not allowed to delete a comment if not connected")}
|
||||
end
|
||||
|
||||
@spec do_delete_comment(CommentModel.t(), Actor.t()) ::
|
||||
{:ok, CommentModel.t()} | {:error, any()}
|
||||
defp do_delete_comment(%CommentModel{} = comment, %Actor{} = actor) do
|
||||
with {:ok, _, %CommentModel{} = comment} <-
|
||||
Comments.delete_comment(comment, actor) do
|
||||
{:ok, comment}
|
||||
case Comments.delete_comment(comment, actor) do
|
||||
{:ok, _, %CommentModel{} = comment} ->
|
||||
{:ok, comment}
|
||||
|
||||
{:error, err} ->
|
||||
{:error, err}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
||||
@doc """
|
||||
Gets config.
|
||||
"""
|
||||
@spec get_config(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()}
|
||||
def get_config(_parent, _params, %{context: %{ip: ip}}) do
|
||||
geolix = Geolix.lookup(ip)
|
||||
|
||||
@@ -28,6 +29,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
||||
{:ok, data}
|
||||
end
|
||||
|
||||
@spec terms(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()}
|
||||
def terms(_parent, %{locale: locale}, _resolution) do
|
||||
type = Config.instance_terms_type()
|
||||
|
||||
@@ -41,6 +43,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
||||
{:ok, %{body_html: body_html, type: type, url: url}}
|
||||
end
|
||||
|
||||
@spec privacy(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()}
|
||||
def privacy(_parent, %{locale: locale}, _resolution) do
|
||||
type = Config.instance_privacy_type()
|
||||
|
||||
@@ -54,6 +57,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
||||
{:ok, %{body_html: body_html, type: type, url: url}}
|
||||
end
|
||||
|
||||
@spec config_cache :: map()
|
||||
defp config_cache do
|
||||
case Cachex.fetch(:config, "full_config", fn _key ->
|
||||
case build_config_cache() do
|
||||
@@ -62,10 +66,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
||||
end
|
||||
end) do
|
||||
{status, value} when status in [:ok, :commit] -> value
|
||||
_err -> nil
|
||||
_err -> %{}
|
||||
end
|
||||
end
|
||||
|
||||
@spec build_config_cache :: map()
|
||||
defp build_config_cache do
|
||||
%{
|
||||
name: Config.instance_name(),
|
||||
|
||||
@@ -6,12 +6,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
alias Mobilizon.{Actors, Discussions}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.GraphQL.API.Comments
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
import Mobilizon.Web.Gettext
|
||||
|
||||
@spec find_discussions_for_actor(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Discussion.t())} | {:error, :unauthenticated}
|
||||
def find_discussions_for_actor(
|
||||
%Actor{id: group_id},
|
||||
%{page: page, limit: limit},
|
||||
@@ -30,19 +32,33 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
end
|
||||
end
|
||||
|
||||
def find_discussions_for_actor(%Actor{}, _args, _resolution) do
|
||||
def find_discussions_for_actor(%Actor{}, _args, %{
|
||||
context: %{
|
||||
current_user: %User{}
|
||||
}
|
||||
}) do
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
def find_discussions_for_actor(%Actor{}, _args, _resolution), do: {:error, :unauthenticated}
|
||||
|
||||
@spec get_discussion(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Discussion.t()} | {:error, :unauthorized | :discussion_not_found | String.t()}
|
||||
def get_discussion(_parent, %{id: id}, %{
|
||||
context: %{
|
||||
current_actor: %Actor{id: creator_id}
|
||||
}
|
||||
}) do
|
||||
with %Discussion{actor_id: actor_id} = discussion <-
|
||||
Discussions.get_discussion(id),
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)} do
|
||||
{:ok, discussion}
|
||||
case Discussions.get_discussion(id) do
|
||||
%Discussion{actor_id: actor_id} = discussion ->
|
||||
if Actors.is_member?(creator_id, actor_id) do
|
||||
{:ok, discussion}
|
||||
else
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
|
||||
nil ->
|
||||
{:error, :discussion_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -73,6 +89,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
def get_discussion(_parent, _args, _resolution),
|
||||
do: {:error, dgettext("errors", "You need to be logged-in to access discussions")}
|
||||
|
||||
@spec get_comments_for_discussion(Discussion.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Discussion.t())}
|
||||
def get_comments_for_discussion(
|
||||
%Discussion{id: discussion_id},
|
||||
%{page: page, limit: limit},
|
||||
@@ -81,6 +99,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
{:ok, Discussions.get_comments_for_discussion(discussion_id, page, limit)}
|
||||
end
|
||||
|
||||
@spec create_discussion(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Discussion.t()}
|
||||
| {:error, Ecto.Changeset.t() | String.t() | :unauthorized | :unauthenticated}
|
||||
def create_discussion(
|
||||
_parent,
|
||||
%{title: title, text: text, actor_id: group_id},
|
||||
@@ -90,27 +111,32 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(creator_id, group_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
Comments.create_discussion(%{
|
||||
if Actors.is_member?(creator_id, group_id) do
|
||||
case Comments.create_discussion(%{
|
||||
title: title,
|
||||
text: text,
|
||||
actor_id: group_id,
|
||||
creator_id: creator_id,
|
||||
attributed_to_id: group_id
|
||||
}) do
|
||||
{:ok, discussion}
|
||||
else
|
||||
{:error, type, err, _} when type in [:discussion, :comment] ->
|
||||
{:error, err}
|
||||
{:ok, _activity, %Discussion{} = discussion} ->
|
||||
{:ok, discussion}
|
||||
|
||||
{:member, false} ->
|
||||
{:error, :unauthorized}
|
||||
{:error, %Ecto.Changeset{} = err} ->
|
||||
{:error, err}
|
||||
|
||||
{:error, _err} ->
|
||||
{:error, dgettext("errors", "Error while creating a discussion")}
|
||||
end
|
||||
else
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
end
|
||||
|
||||
def create_discussion(_, _, _), do: {:error, :unauthenticated}
|
||||
|
||||
@spec reply_to_discussion(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Discussion.t()} | {:error, :discussion_not_found | :unauthenticated}
|
||||
def reply_to_discussion(
|
||||
_parent,
|
||||
%{text: text, discussion_id: discussion_id},
|
||||
@@ -150,7 +176,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
|
||||
def reply_to_discussion(_, _, _), do: {:error, :unauthenticated}
|
||||
|
||||
@spec update_discussion(map(), map(), map()) :: {:ok, Discussion.t()}
|
||||
@spec update_discussion(map(), map(), map()) ::
|
||||
{:ok, Discussion.t()} | {:error, :unauthorized | :unauthenticated}
|
||||
def update_discussion(
|
||||
_parent,
|
||||
%{title: title, discussion_id: discussion_id},
|
||||
@@ -164,7 +191,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
ActivityPub.update(
|
||||
Actions.Update.update(
|
||||
discussion,
|
||||
%{
|
||||
title: title
|
||||
@@ -179,6 +206,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
|
||||
def update_discussion(_, _, _), do: {:error, :unauthenticated}
|
||||
|
||||
@spec delete_discussion(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Discussion.t()} | {:error, String.t() | :unauthorized | :unauthenticated}
|
||||
def delete_discussion(_parent, %{discussion_id: discussion_id}, %{
|
||||
context: %{
|
||||
current_user: %User{},
|
||||
@@ -189,7 +218,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
ActivityPub.delete(discussion, actor) do
|
||||
Actions.Delete.delete(discussion, actor) do
|
||||
{:ok, discussion}
|
||||
else
|
||||
{:no_discussion, _} ->
|
||||
|
||||
@@ -21,6 +21,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
@event_max_limit 100
|
||||
@number_of_related_events 3
|
||||
|
||||
@spec organizer_for_event(Event.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t() | nil} | {:error, String.t()}
|
||||
def organizer_for_event(
|
||||
%Event{attributed_to_id: attributed_to_id, organizer_actor_id: organizer_actor_id},
|
||||
_args,
|
||||
@@ -62,6 +64,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
end
|
||||
end
|
||||
|
||||
@spec list_events(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Event.t())} | {:error, :events_max_limit_reached}
|
||||
def list_events(
|
||||
_parent,
|
||||
%{page: page, limit: limit, order_by: order_by, direction: direction},
|
||||
@@ -75,6 +79,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
{:error, :events_max_limit_reached}
|
||||
end
|
||||
|
||||
@spec find_private_event(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Event.t()} | {:error, :event_not_found}
|
||||
defp find_private_event(
|
||||
_parent,
|
||||
%{uuid: uuid},
|
||||
@@ -106,6 +112,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
{:error, :event_not_found}
|
||||
end
|
||||
|
||||
@spec find_event(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Event.t()} | {:error, :event_not_found}
|
||||
def find_event(parent, %{uuid: uuid} = args, %{context: context} = resolution) do
|
||||
with {:has_event, %Event{} = event} <-
|
||||
{:has_event, Events.get_public_event_by_uuid_with_preload(uuid)},
|
||||
@@ -132,6 +140,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
@doc """
|
||||
List participants for event (through an event request)
|
||||
"""
|
||||
@spec list_participants_for_event(Event.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Participant.t())} | {:error, String.t()}
|
||||
def list_participants_for_event(
|
||||
%Event{id: event_id} = event,
|
||||
%{page: page, limit: limit, roles: roles},
|
||||
@@ -166,6 +176,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
{:ok, %{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
@spec stats_participants(Event.t(), map(), Absinthe.Resolution.t()) :: {:ok, map()}
|
||||
def stats_participants(
|
||||
%Event{participant_stats: %EventParticipantStats{} = stats, id: event_id} = _event,
|
||||
_args,
|
||||
@@ -198,6 +209,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
@doc """
|
||||
List related events
|
||||
"""
|
||||
@spec list_related_events(Event.t(), map(), Absinthe.Resolution.t()) :: {:ok, list(Event.t())}
|
||||
def list_related_events(
|
||||
%Event{tags: tags, organizer_actor: organizer_actor, uuid: uuid},
|
||||
_args,
|
||||
@@ -239,11 +251,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
{:ok, events}
|
||||
end
|
||||
|
||||
@spec uniq_events(list(Event.t())) :: list(Event.t())
|
||||
defp uniq_events(events), do: Enum.uniq_by(events, fn event -> event.uuid end)
|
||||
|
||||
@doc """
|
||||
Create an event
|
||||
"""
|
||||
@spec create_event(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Event.t()} | {:error, String.t() | Ecto.Changeset.t()}
|
||||
def create_event(
|
||||
_parent,
|
||||
%{organizer_actor_id: organizer_actor_id} = args,
|
||||
@@ -283,6 +298,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
@doc """
|
||||
Update an event
|
||||
"""
|
||||
@spec update_event(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Event.t()} | {:error, String.t() | Ecto.Changeset.t()}
|
||||
def update_event(
|
||||
_parent,
|
||||
%{event_id: event_id} = args,
|
||||
@@ -327,6 +344,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
@doc """
|
||||
Delete an event
|
||||
"""
|
||||
@spec delete_event(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Event.t()} | {:error, String.t() | Ecto.Changeset.t()}
|
||||
def delete_event(
|
||||
_parent,
|
||||
%{event_id: event_id},
|
||||
@@ -365,6 +384,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
{:error, dgettext("errors", "You need to be logged-in to delete an event")}
|
||||
end
|
||||
|
||||
@spec do_delete_event(Event.t(), Actor.t(), boolean()) :: {:ok, map()}
|
||||
defp do_delete_event(%Event{} = event, %Actor{} = actor, federate \\ true)
|
||||
when is_boolean(federate) do
|
||||
with {:ok, _activity, event} <- API.Events.delete_event(event, actor) do
|
||||
@@ -372,6 +392,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
end
|
||||
end
|
||||
|
||||
@spec is_organizer_group_member?(map()) :: boolean()
|
||||
defp is_organizer_group_member?(%{
|
||||
attributed_to_id: attributed_to_id,
|
||||
organizer_actor_id: organizer_actor_id
|
||||
@@ -383,6 +404,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
||||
|
||||
defp is_organizer_group_member?(_), do: true
|
||||
|
||||
@spec verify_profile_change(map(), Event.t(), User.t(), Actor.t()) :: {:ok, map()}
|
||||
defp verify_profile_change(
|
||||
args,
|
||||
%Event{attributed_to: %Actor{}},
|
||||
|
||||
@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Followers do
|
||||
import Mobilizon.Users.Guards
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
@@ -43,9 +43,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Followers do
|
||||
{:member, Actors.is_moderator?(actor_id, group_id)},
|
||||
{:ok, _activity, %Follower{} = follower} <-
|
||||
(if approved do
|
||||
ActivityPub.accept(:follow, follower)
|
||||
Actions.Accept.accept(:follow, follower)
|
||||
else
|
||||
ActivityPub.reject(:follow, follower)
|
||||
Actions.Reject.reject(:follow, follower)
|
||||
end) do
|
||||
{:ok, follower}
|
||||
else
|
||||
|
||||
@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
import Mobilizon.Users.Guards
|
||||
alias Mobilizon.{Actors, Events}
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
|
||||
alias Mobilizon.GraphQL.API
|
||||
alias Mobilizon.Users.User
|
||||
@@ -15,6 +15,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
|
||||
require Logger
|
||||
|
||||
@spec find_group(
|
||||
any,
|
||||
%{:preferred_username => binary, optional(any) => any},
|
||||
Absinthe.Resolution.t()
|
||||
) ::
|
||||
{:error, :group_not_found} | {:ok, Actor.t()}
|
||||
@doc """
|
||||
Find a group
|
||||
"""
|
||||
@@ -27,29 +33,26 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:group, {:ok, %Actor{id: group_id, suspended: false} = group}} <-
|
||||
{:group, ActivityPubActor.find_or_make_group_from_nickname(name)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
|
||||
{:ok, group}
|
||||
else
|
||||
{:member, false} ->
|
||||
find_group(parent, args, nil)
|
||||
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
|
||||
|
||||
{:group, _} ->
|
||||
{:error, _err} ->
|
||||
{:error, :group_not_found}
|
||||
|
||||
_ ->
|
||||
{:error, :unknown}
|
||||
end
|
||||
end
|
||||
|
||||
def find_group(_parent, %{preferred_username: name}, _resolution) do
|
||||
with {:ok, %Actor{suspended: false} = actor} <-
|
||||
ActivityPubActor.find_or_make_group_from_nickname(name),
|
||||
%Actor{} = actor <- restrict_fields_for_non_member_request(actor) do
|
||||
{:ok, actor}
|
||||
else
|
||||
_ ->
|
||||
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}
|
||||
|
||||
{:error, _err} ->
|
||||
{:error, :group_not_found}
|
||||
end
|
||||
end
|
||||
@@ -57,13 +60,18 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
@doc """
|
||||
Get a group
|
||||
"""
|
||||
@spec get_group(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t()}
|
||||
def get_group(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}}) do
|
||||
with %Actor{type: :Group, suspended: suspended} = actor <-
|
||||
Actors.get_actor_with_preload(id, true),
|
||||
true <- suspended == false or is_moderator(role) do
|
||||
{:ok, actor}
|
||||
else
|
||||
_ ->
|
||||
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 ->
|
||||
{:error, dgettext("errors", "Group with ID %{id} not found", id: id)}
|
||||
end
|
||||
end
|
||||
@@ -71,6 +79,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
@doc """
|
||||
Lists all groups
|
||||
"""
|
||||
@spec list_groups(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Actor.t())} | {:error, String.t()}
|
||||
def list_groups(
|
||||
_parent,
|
||||
%{
|
||||
@@ -95,6 +105,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
do: {:error, dgettext("errors", "You may not list groups unless moderator.")}
|
||||
|
||||
# TODO Move me to somewhere cleaner
|
||||
@spec save_attached_pictures(map()) :: map()
|
||||
defp save_attached_pictures(args) do
|
||||
Enum.reduce([:avatar, :banner], args, fn key, args ->
|
||||
if is_map(args) && Map.has_key?(args, key) && !is_nil(args[key][:media]) do
|
||||
@@ -113,6 +124,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
@doc """
|
||||
Create a new group. The creator is automatically added as admin
|
||||
"""
|
||||
@spec create_group(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t()}
|
||||
def create_group(
|
||||
_parent,
|
||||
args,
|
||||
@@ -145,6 +158,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
@doc """
|
||||
Update a group. The creator is automatically added as admin
|
||||
"""
|
||||
@spec update_group(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t()}
|
||||
def update_group(
|
||||
_parent,
|
||||
%{id: group_id} = args,
|
||||
@@ -154,22 +169,24 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
}
|
||||
}
|
||||
) do
|
||||
with {:administrator, true} <-
|
||||
{:administrator, Actors.is_administrator?(updater_actor.id, group_id)},
|
||||
args when is_map(args) <- Map.put(args, :updater_actor, updater_actor),
|
||||
{:picture, args} when is_map(args) <- {:picture, save_attached_pictures(args)},
|
||||
{:ok, _activity, %Actor{type: :Group} = group} <-
|
||||
API.Groups.update_group(args) do
|
||||
{:ok, group}
|
||||
if Actors.is_administrator?(updater_actor.id, group_id) do
|
||||
args = Map.put(args, :updater_actor, updater_actor)
|
||||
|
||||
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}
|
||||
|
||||
{:error, _err} ->
|
||||
{:error, dgettext("errors", "Failed to update the group")}
|
||||
end
|
||||
end
|
||||
else
|
||||
{:picture, {:error, :file_too_large}} ->
|
||||
{:error, dgettext("errors", "The provided picture is too heavy")}
|
||||
|
||||
{:error, err} when is_binary(err) ->
|
||||
{:error, err}
|
||||
|
||||
{:administrator, false} ->
|
||||
{:error, dgettext("errors", "Profile is not administrator for the group")}
|
||||
{:error, dgettext("errors", "Profile is not administrator for the group")}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -180,6 +197,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
@doc """
|
||||
Delete an existing group
|
||||
"""
|
||||
@spec delete_group(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, %{id: integer()}} | {:error, String.t()}
|
||||
def delete_group(
|
||||
_parent,
|
||||
%{group_id: group_id},
|
||||
@@ -192,7 +211,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
with {:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
|
||||
{:ok, %Member{} = member} <- Actors.get_member(actor_id, group.id),
|
||||
{:is_admin, true} <- {:is_admin, Member.is_administrator(member)},
|
||||
{:ok, _activity, group} <- ActivityPub.delete(group, actor, true) do
|
||||
{:ok, _activity, group} <- Actions.Delete.delete(group, actor, true) do
|
||||
{:ok, %{id: group.id}}
|
||||
else
|
||||
{:error, :group_not_found} ->
|
||||
@@ -214,6 +233,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
@doc """
|
||||
Join an existing group
|
||||
"""
|
||||
@spec join_group(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Member.t()} | {:error, String.t()}
|
||||
def join_group(_parent, %{group_id: group_id} = args, %{
|
||||
context: %{current_actor: %Actor{} = actor}
|
||||
}) do
|
||||
@@ -222,7 +243,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
{:error, :member_not_found} <- Actors.get_member(actor.id, group.id),
|
||||
{:is_able_to_join, true} <- {:is_able_to_join, Member.can_be_joined(group)},
|
||||
{:ok, _activity, %Member{} = member} <-
|
||||
ActivityPub.join(group, actor, true, args) do
|
||||
Actions.Join.join(group, actor, true, args) do
|
||||
{:ok, member}
|
||||
else
|
||||
{:error, :group_not_found} ->
|
||||
@@ -243,6 +264,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
@doc """
|
||||
Leave a existing group
|
||||
"""
|
||||
@spec leave_group(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Member.t()} | {:error, String.t()}
|
||||
def leave_group(
|
||||
_parent,
|
||||
%{group_id: group_id},
|
||||
@@ -253,7 +276,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
}
|
||||
) do
|
||||
with {:group, %Actor{type: :Group} = group} <- {:group, Actors.get_actor(group_id)},
|
||||
{:ok, _activity, %Member{} = member} <- ActivityPub.leave(group, actor, true) do
|
||||
{:ok, _activity, %Member{} = member} <-
|
||||
Actions.Leave.leave(group, actor, true) do
|
||||
{:ok, member}
|
||||
else
|
||||
{:error, :member_not_found} ->
|
||||
@@ -262,7 +286,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
{:group, nil} ->
|
||||
{:error, dgettext("errors", "Group not found")}
|
||||
|
||||
{:is_not_only_admin, false} ->
|
||||
{:error, :is_not_only_admin} ->
|
||||
{:error,
|
||||
dgettext("errors", "You can't leave this group because you are the only administrator")}
|
||||
end
|
||||
@@ -272,6 +296,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
{:error, dgettext("errors", "You need to be logged-in to leave a group")}
|
||||
end
|
||||
|
||||
@spec find_events_for_group(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Event.t())}
|
||||
def find_events_for_group(
|
||||
%Actor{id: group_id} = group,
|
||||
%{
|
||||
@@ -320,16 +346,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
||||
)}
|
||||
end
|
||||
|
||||
@spec restrict_fields_for_non_member_request(Actor.t()) :: Actor.t()
|
||||
defp restrict_fields_for_non_member_request(%Actor{} = group) do
|
||||
Map.merge(
|
||||
group,
|
||||
%{
|
||||
followers: [],
|
||||
%Actor{
|
||||
group
|
||||
| followers: [],
|
||||
followings: [],
|
||||
organized_events: [],
|
||||
comments: [],
|
||||
feed_tokens: []
|
||||
}
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
import Mobilizon.Users.Guards
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
@@ -17,6 +17,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
|
||||
If actor requesting is not part of the group, we only return the number of members, not members
|
||||
"""
|
||||
@spec find_members_for_group(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Member.t())}
|
||||
def find_members_for_group(
|
||||
%Actor{id: group_id} = group,
|
||||
%{page: page, limit: limit, roles: roles},
|
||||
@@ -47,11 +49,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
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
|
||||
%Page{} = page = Actors.list_members_for_group(group)
|
||||
{:ok, %Page{page | elements: []}}
|
||||
end
|
||||
|
||||
@spec invite_member(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Member.t()} | {:error, String.t()}
|
||||
def invite_member(
|
||||
_parent,
|
||||
%{group_id: group_id, target_actor_username: target_actor_username},
|
||||
@@ -68,7 +71,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
ActivityPubActor.find_or_make_actor_from_nickname(target_actor_username)},
|
||||
{:existant, true} <-
|
||||
{:existant, check_member_not_existant_or_rejected(target_actor_id, group.id)},
|
||||
{:ok, _activity, %Member{} = member} <- ActivityPub.invite(group, actor, target_actor) do
|
||||
{:ok, _activity, %Member{} = member} <-
|
||||
Actions.Invite.invite(group, actor, target_actor) do
|
||||
{:ok, member}
|
||||
else
|
||||
{:error, :group_not_found} ->
|
||||
@@ -92,6 +96,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
end
|
||||
end
|
||||
|
||||
@spec accept_invitation(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Member.t()} | {:error, String.t()}
|
||||
def accept_invitation(_parent, %{id: member_id}, %{
|
||||
context: %{current_actor: %Actor{id: actor_id}}
|
||||
}) do
|
||||
@@ -99,7 +105,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
Actors.get_member(member_id),
|
||||
{:is_same_actor, true} <- {:is_same_actor, member_actor_id == actor_id},
|
||||
{:ok, _activity, %Member{} = member} <-
|
||||
ActivityPub.accept(
|
||||
Actions.Accept.accept(
|
||||
:invite,
|
||||
member,
|
||||
true
|
||||
@@ -111,6 +117,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
end
|
||||
end
|
||||
|
||||
@spec reject_invitation(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Member.t()} | {:error, String.t()}
|
||||
def reject_invitation(_parent, %{id: member_id}, %{
|
||||
context: %{current_actor: %Actor{id: actor_id}}
|
||||
}) do
|
||||
@@ -118,7 +126,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
{:invitation_exists, Actors.get_member(member_id)},
|
||||
{:is_same_actor, true} <- {:is_same_actor, member_actor_id == actor_id},
|
||||
{:ok, _activity, %Member{} = member} <-
|
||||
ActivityPub.reject(
|
||||
Actions.Reject.reject(
|
||||
:invite,
|
||||
member,
|
||||
true
|
||||
@@ -133,12 +141,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
end
|
||||
end
|
||||
|
||||
@spec update_member(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Member.t()} | {:error, String.t()}
|
||||
def update_member(_parent, %{member_id: member_id, role: role}, %{
|
||||
context: %{current_actor: %Actor{} = moderator}
|
||||
}) do
|
||||
with %Member{} = member <- Actors.get_member(member_id),
|
||||
{:ok, _activity, %Member{} = member} <-
|
||||
ActivityPub.update(member, %{role: role}, true, %{moderator: moderator}) do
|
||||
Actions.Update.update(member, %{role: role}, true, %{moderator: moderator}) do
|
||||
{:ok, member}
|
||||
else
|
||||
{:error, :member_not_found} ->
|
||||
@@ -156,6 +166,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
def update_member(_parent, _args, _resolution),
|
||||
do: {:error, "You must be logged-in to update a member"}
|
||||
|
||||
@spec remove_member(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Member.t()} | {:error, String.t()}
|
||||
def remove_member(_parent, %{member_id: member_id, group_id: group_id}, %{
|
||||
context: %{current_actor: %Actor{id: moderator_id} = moderator}
|
||||
}) do
|
||||
@@ -164,7 +176,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
||||
{:has_rights_to_remove, {:ok, %Member{role: role}}}
|
||||
when role in [:moderator, :administrator, :creator] <-
|
||||
{:has_rights_to_remove, Actors.get_member(moderator_id, group_id)},
|
||||
{:ok, _activity, %Member{}} <- ActivityPub.remove(member, group, moderator, true) do
|
||||
{:ok, _activity, %Member{}} <-
|
||||
Actions.Remove.remove(member, group, moderator, true) do
|
||||
{:ok, member}
|
||||
else
|
||||
%Member{role: :rejected} ->
|
||||
|
||||
@@ -16,6 +16,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
|
||||
@doc """
|
||||
Join an event for an regular or anonymous actor
|
||||
"""
|
||||
@spec actor_join_event(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Participant.t()} | {:error, String.t()}
|
||||
def actor_join_event(
|
||||
_parent,
|
||||
%{actor_id: actor_id, event_id: event_id} = args,
|
||||
@@ -157,6 +159,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
|
||||
@doc """
|
||||
Leave an event for an anonymous actor
|
||||
"""
|
||||
@spec actor_leave_event(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, map()} | {:error, String.t()}
|
||||
def actor_leave_event(
|
||||
_parent,
|
||||
%{actor_id: actor_id, event_id: event_id, token: token},
|
||||
@@ -220,6 +224,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
|
||||
{:error, dgettext("errors", "You need to be logged-in to leave an event")}
|
||||
end
|
||||
|
||||
@spec update_participation(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Participation.t()} | {:error, String.t()}
|
||||
def update_participation(
|
||||
_parent,
|
||||
%{id: participation_id, role: new_role},
|
||||
|
||||
@@ -12,7 +12,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
alias Mobilizon.Users.User
|
||||
import Mobilizon.Web.Gettext
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
|
||||
require Logger
|
||||
|
||||
@@ -21,6 +21,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
@doc """
|
||||
Get a person
|
||||
"""
|
||||
@spec get_person(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t() | :unauthorized}
|
||||
def get_person(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}}) do
|
||||
with %Actor{suspended: suspended} = actor <- Actors.get_actor_with_preload(id, true),
|
||||
true <- suspended == false or is_moderator(role) do
|
||||
@@ -36,6 +38,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
@doc """
|
||||
Find a person
|
||||
"""
|
||||
@spec fetch_person(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t() | :unauthorized | :unauthenticated}
|
||||
def fetch_person(_parent, %{preferred_username: preferred_username}, %{
|
||||
context: %{current_user: %User{} = user}
|
||||
}) do
|
||||
@@ -57,6 +61,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
|
||||
def fetch_person(_parent, _args, _resolution), do: {:error, :unauthenticated}
|
||||
|
||||
@spec list_persons(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Actor.t())} | {:error, :unauthorized | :unauthenticated}
|
||||
def list_persons(
|
||||
_parent,
|
||||
%{
|
||||
@@ -92,7 +98,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
Returns the current actor for the currently logged-in user
|
||||
"""
|
||||
@spec get_current_person(any, any, Absinthe.Resolution.t()) ::
|
||||
{:error, :unauthenticated} | {:ok, Actor.t()}
|
||||
{:error, :unauthenticated | :no_current_person} | {:ok, Actor.t()}
|
||||
def get_current_person(_parent, _args, %{context: %{current_actor: %Actor{} = actor}}) do
|
||||
{:ok, actor}
|
||||
end
|
||||
@@ -121,6 +127,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
@doc """
|
||||
This function is used to create more identities from an existing user
|
||||
"""
|
||||
@spec create_person(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t() | :unauthenticated}
|
||||
def create_person(
|
||||
_parent,
|
||||
%{preferred_username: _preferred_username} = args,
|
||||
@@ -148,6 +156,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
@doc """
|
||||
This function is used to update an existing identity
|
||||
"""
|
||||
@spec update_person(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t() | :unauthenticated}
|
||||
def update_person(
|
||||
_parent,
|
||||
%{id: id} = args,
|
||||
@@ -160,7 +170,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
{:ok, %Actor{} = actor} ->
|
||||
case save_attached_pictures(args) do
|
||||
args when is_map(args) ->
|
||||
case ActivityPub.update(actor, args, true) do
|
||||
case Actions.Update.update(actor, args, true) do
|
||||
{:ok, _activity, %Actor{} = actor} ->
|
||||
{:ok, actor}
|
||||
|
||||
@@ -184,6 +194,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
@doc """
|
||||
This function is used to delete an existing identity
|
||||
"""
|
||||
@spec delete_person(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t() | :unauthenticated}
|
||||
def delete_person(
|
||||
_parent,
|
||||
%{id: id} = _args,
|
||||
@@ -225,6 +237,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
end
|
||||
end
|
||||
|
||||
@spec last_identity?(User.t()) :: boolean
|
||||
defp last_identity?(user) do
|
||||
length(Users.get_actors_for_user(user)) <= 1
|
||||
end
|
||||
@@ -275,6 +288,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
@doc """
|
||||
This function is used to register a person afterwards the user has been created (but not activated)
|
||||
"""
|
||||
@spec register_person(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Actor.t()} | {:error, String.t()}
|
||||
def register_person(_parent, args, _resolution) do
|
||||
# When registering, email is assumed confirmed (unlike changing email)
|
||||
case Users.get_user_by_email(args.email, unconfirmed: false) do
|
||||
@@ -311,6 +326,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
@doc """
|
||||
Returns the participations, optionally restricted to an event
|
||||
"""
|
||||
@spec person_participations(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Participant.t())} | {:error, :unauthorized | String.t()}
|
||||
def person_participations(
|
||||
%Actor{id: actor_id} = person,
|
||||
%{event_id: event_id},
|
||||
@@ -329,13 +346,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
def person_participations(%Actor{} = person, %{page: page, limit: limit}, %{
|
||||
context: %{current_user: %User{} = user}
|
||||
}) do
|
||||
with {:can_get_participations, true} <-
|
||||
{:can_get_participations, user_can_access_person_details?(person, user)},
|
||||
%Page{} = page <- Events.list_event_participations_for_actor(person, page, limit) do
|
||||
if user_can_access_person_details?(person, user) do
|
||||
%Page{} = page = Events.list_event_participations_for_actor(person, page, limit)
|
||||
{:ok, page}
|
||||
else
|
||||
{:can_get_participations, false} ->
|
||||
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
|
||||
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -346,24 +361,23 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
def person_memberships(%Actor{id: actor_id} = person, %{group: group}, %{
|
||||
context: %{current_user: %User{} = user}
|
||||
}) do
|
||||
with {:can_get_memberships, true} <-
|
||||
{:can_get_memberships, user_can_access_person_details?(person, user)},
|
||||
{:group, %Actor{id: group_id}} <- {:group, Actors.get_actor_by_name(group, :Group)},
|
||||
{:ok, %Member{} = membership} <- Actors.get_member(actor_id, group_id),
|
||||
memberships <- %Page{
|
||||
if user_can_access_person_details?(person, user) do
|
||||
with {:group, %Actor{id: group_id}} <- {:group, Actors.get_actor_by_name(group, :Group)},
|
||||
{:ok, %Member{} = membership} <- Actors.get_member(actor_id, group_id) do
|
||||
{:ok,
|
||||
%Page{
|
||||
total: 1,
|
||||
elements: [Repo.preload(membership, [:actor, :parent, :invited_by])]
|
||||
} do
|
||||
{:ok, memberships}
|
||||
}}
|
||||
else
|
||||
{:error, :member_not_found} ->
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
|
||||
{:group, nil} ->
|
||||
{:error, :group_not_found}
|
||||
end
|
||||
else
|
||||
{:error, :member_not_found} ->
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
|
||||
{:group, nil} ->
|
||||
{:error, :group_not_found}
|
||||
|
||||
{:can_get_memberships, _} ->
|
||||
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
|
||||
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -384,6 +398,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
end
|
||||
end
|
||||
|
||||
@spec user_for_person(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, User.t() | nil} | {:error, String.t() | nil}
|
||||
def user_for_person(%Actor{type: :Person, user_id: user_id}, _args, %{
|
||||
context: %{current_user: %User{role: role}}
|
||||
})
|
||||
@@ -402,6 +418,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
|
||||
def user_for_person(_, _args, _resolution), do: {:error, nil}
|
||||
|
||||
@spec organized_events_for_person(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Event.t())} | {:error, :unauthorized}
|
||||
def organized_events_for_person(
|
||||
%Actor{} = person,
|
||||
%{page: page, limit: limit},
|
||||
@@ -409,13 +427,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
||||
context: %{current_user: %User{} = user}
|
||||
}
|
||||
) do
|
||||
with {:can_get_events, true} <-
|
||||
{:can_get_events, user_can_access_person_details?(person, user)},
|
||||
%Page{} = page <- Events.list_organized_events_for_actor(person, page, limit) do
|
||||
if user_can_access_person_details?(person, user) do
|
||||
%Page{} = page = Events.list_organized_events_for_actor(person, page, limit)
|
||||
{:ok, page}
|
||||
else
|
||||
{:can_get_events, false} ->
|
||||
{:error, :unauthorized}
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,8 +6,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
import Mobilizon.Users.Guards
|
||||
alias Mobilizon.{Actors, Posts}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.{Permission, Utils}
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Permission, Utils}
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
@@ -22,6 +21,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
|
||||
Returns only if actor requesting is a member of the group
|
||||
"""
|
||||
@spec find_posts_for_group(Actor.t(), map(), Absinthe.Resolution.t()) :: {:ok, Page.t(Post.t())}
|
||||
def find_posts_for_group(
|
||||
%Actor{id: group_id} = group,
|
||||
%{page: page, limit: limit} = args,
|
||||
@@ -32,13 +32,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:member, true} <-
|
||||
{:member, Actors.is_member?(actor_id, group_id) or is_moderator(user_role)},
|
||||
%Page{} = page <- Posts.get_posts_for_group(group, page, limit) do
|
||||
if Actors.is_member?(actor_id, group_id) or is_moderator(user_role) do
|
||||
%Page{} = page = Posts.get_posts_for_group(group, page, limit)
|
||||
{:ok, page}
|
||||
else
|
||||
{:member, _} ->
|
||||
find_posts_for_group(group, args, nil)
|
||||
find_posts_for_group(group, args, nil)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,9 +45,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
%{page: page, limit: limit},
|
||||
_resolution
|
||||
) do
|
||||
with %Page{} = page <- Posts.get_public_posts_for_group(group, page, limit) do
|
||||
{:ok, page}
|
||||
end
|
||||
%Page{} = page = Posts.get_public_posts_for_group(group, page, limit)
|
||||
{:ok, page}
|
||||
end
|
||||
|
||||
def find_posts_for_group(
|
||||
@@ -60,6 +57,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
@spec get_post(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Post.t()} | {:error, :post_not_found}
|
||||
def get_post(
|
||||
parent,
|
||||
%{slug: slug},
|
||||
@@ -101,6 +100,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
{:error, :post_not_found}
|
||||
end
|
||||
|
||||
@spec create_post(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Post.t()} | {:error, String.t()}
|
||||
def create_post(
|
||||
_parent,
|
||||
%{attributed_to_id: group_id} = args,
|
||||
@@ -118,7 +119,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
end),
|
||||
args <- extract_pictures_from_post_body(args, actor_id),
|
||||
{:ok, _, %Post{} = post} <-
|
||||
ActivityPub.create(
|
||||
Actions.Create.create(
|
||||
:post,
|
||||
args
|
||||
|> Map.put(:author_id, actor_id)
|
||||
@@ -140,6 +141,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
{:error, dgettext("errors", "You need to be logged-in to create posts")}
|
||||
end
|
||||
|
||||
@spec update_post(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Post.t()} | {:error, String.t()}
|
||||
def update_post(
|
||||
_parent,
|
||||
%{id: id} = args,
|
||||
@@ -159,7 +162,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
args <- extract_pictures_from_post_body(args, actor_id),
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Post{} = post} <-
|
||||
ActivityPub.update(post, args, true, %{"actor" => actor_url}) do
|
||||
Actions.Update.update(post, args, true, %{"actor" => actor_url}) do
|
||||
{:ok, post}
|
||||
else
|
||||
{:uuid, :error} ->
|
||||
@@ -177,6 +180,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
{:error, dgettext("errors", "You need to be logged-in to update posts")}
|
||||
end
|
||||
|
||||
@spec delete_post(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Post.t()} | {:error, String.t()}
|
||||
def delete_post(
|
||||
_parent,
|
||||
%{id: post_id},
|
||||
@@ -191,7 +196,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
{:post, Posts.get_post_with_preloads(post_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Post{} = post} <-
|
||||
ActivityPub.delete(post, actor) do
|
||||
Actions.Delete.delete(post, actor) do
|
||||
{:ok, post}
|
||||
else
|
||||
{:uuid, :error} ->
|
||||
@@ -209,6 +214,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
||||
{:error, dgettext("errors", "You need to be logged-in to delete posts")}
|
||||
end
|
||||
|
||||
@spec process_picture(map() | nil, Actor.t()) :: nil | map()
|
||||
defp process_picture(nil, _), do: nil
|
||||
defp process_picture(%{media_id: _picture_id} = args, _), do: args
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ defmodule Mobilizon.GraphQL.Resolvers.PushSubscription do
|
||||
@doc """
|
||||
List all of an user's registered push subscriptions
|
||||
"""
|
||||
@spec list_user_push_subscriptions(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(PushSubscription.t())} | {:error, :unauthenticated}
|
||||
def list_user_push_subscriptions(_parent, %{page: page, limit: limit}, %{
|
||||
context: %{current_user: %User{id: user_id}}
|
||||
}) do
|
||||
@@ -22,6 +24,8 @@ defmodule Mobilizon.GraphQL.Resolvers.PushSubscription do
|
||||
@doc """
|
||||
Register a push subscription
|
||||
"""
|
||||
@spec register_push_subscription(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, String.t()} | {:error, String.t()}
|
||||
def register_push_subscription(_parent, args, %{
|
||||
context: %{current_user: %User{id: user_id}}
|
||||
}) do
|
||||
|
||||
@@ -13,6 +13,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
|
||||
|
||||
alias Mobilizon.GraphQL.API
|
||||
|
||||
@spec list_reports(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Report.t())} | {:error, String.t()}
|
||||
def list_reports(
|
||||
_parent,
|
||||
%{page: page, limit: limit, status: status},
|
||||
@@ -26,6 +28,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
|
||||
{:error, dgettext("errors", "You need to be logged-in and a moderator to list reports")}
|
||||
end
|
||||
|
||||
@spec get_report(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Report.t()} | {:error, String.t()}
|
||||
def get_report(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
|
||||
when is_moderator(role) do
|
||||
case Mobilizon.Reports.get_report(id) do
|
||||
@@ -44,6 +48,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
|
||||
@doc """
|
||||
Create a report, either logged-in or anonymously
|
||||
"""
|
||||
@spec create_report(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Report.t()} | {:error, String.t()}
|
||||
def create_report(
|
||||
_parent,
|
||||
args,
|
||||
@@ -80,6 +86,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
|
||||
@doc """
|
||||
Update a report's status
|
||||
"""
|
||||
@spec update_report(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Report.t()} | {:error, String.t()}
|
||||
def update_report(
|
||||
_parent,
|
||||
%{report_id: report_id, status: status},
|
||||
@@ -99,6 +107,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
|
||||
{:error, dgettext("errors", "You need to be logged-in and a moderator to update a report")}
|
||||
end
|
||||
|
||||
@spec create_report_note(any(), map(), Absinthe.Resolution.t()) :: {:ok, Note.t()}
|
||||
def create_report_note(
|
||||
_parent,
|
||||
%{report_id: report_id, content: content},
|
||||
@@ -112,6 +121,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
|
||||
end
|
||||
end
|
||||
|
||||
@spec delete_report_note(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()}
|
||||
def delete_report_note(
|
||||
_parent,
|
||||
%{note_id: note_id},
|
||||
|
||||
@@ -5,7 +5,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
|
||||
alias Mobilizon.{Actors, Resources}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.Resources.Resource
|
||||
alias Mobilizon.Resources.Resource.Metadata
|
||||
alias Mobilizon.Service.RichMedia.Parser
|
||||
@@ -21,6 +21,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
|
||||
Returns only if actor requesting is a member of the group
|
||||
"""
|
||||
@spec find_resources_for_group(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Resource.t())}
|
||||
def find_resources_for_group(
|
||||
%Actor{id: group_id} = group,
|
||||
%{page: page, limit: limit},
|
||||
@@ -47,6 +49,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
@spec find_resources_for_parent(Resource.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Resource.t())}
|
||||
def find_resources_for_parent(
|
||||
%Resource{actor_id: group_id} = parent,
|
||||
%{page: page, limit: limit},
|
||||
@@ -65,6 +69,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
def find_resources_for_parent(_parent, _args, _resolution),
|
||||
do: {:ok, %Page{total: 0, elements: []}}
|
||||
|
||||
@spec get_resource(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Resource.t()} | {:error, :group_not_found | :resource_not_found | String.t()}
|
||||
def get_resource(
|
||||
_parent,
|
||||
%{path: path, username: username},
|
||||
@@ -90,6 +96,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:error, dgettext("errors", "You need to be logged-in to access resources")}
|
||||
end
|
||||
|
||||
@spec create_resource(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Resource.t()} | {:error, String.t()}
|
||||
def create_resource(
|
||||
_parent,
|
||||
%{actor_id: group_id} = args,
|
||||
@@ -103,7 +111,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
parent <- get_eventual_parent(args),
|
||||
{:own_check, true} <- {:own_check, check_resource_owned_by_group(parent, group_id)},
|
||||
{:ok, _, %Resource{} = resource} <-
|
||||
ActivityPub.create(
|
||||
Actions.Create.create(
|
||||
:resource,
|
||||
args
|
||||
|> Map.put(:actor_id, group_id)
|
||||
@@ -128,6 +136,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:error, dgettext("errors", "You need to be logged-in to create resources")}
|
||||
end
|
||||
|
||||
@spec update_resource(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Resource.t()} | {:error, String.t()}
|
||||
def update_resource(
|
||||
_parent,
|
||||
%{id: resource_id} = args,
|
||||
@@ -137,18 +147,25 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:resource, %Resource{actor_id: group_id} = resource} <-
|
||||
{:resource, Resources.get_resource_with_preloads(resource_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Resource{} = resource} <-
|
||||
ActivityPub.update(resource, args, true, %{"actor" => actor_url}) do
|
||||
{:ok, resource}
|
||||
else
|
||||
{:resource, _} ->
|
||||
{:error, dgettext("errors", "Resource doesn't exist")}
|
||||
case Resources.get_resource_with_preloads(resource_id) do
|
||||
%Resource{actor_id: group_id} = resource ->
|
||||
if Actors.is_member?(actor_id, group_id) do
|
||||
case Actions.Update.update(resource, args, true, %{"actor" => actor_url}) do
|
||||
{:ok, _, %Resource{} = resource} ->
|
||||
{:ok, resource}
|
||||
|
||||
{:member, _} ->
|
||||
{:error, dgettext("errors", "Profile is not member of group")}
|
||||
{:error, %Ecto.Changeset{} = err} ->
|
||||
{:error, err}
|
||||
|
||||
{:error, err} when is_atom(err) ->
|
||||
{:error, dgettext("errors", "Unknown error while updating resource")}
|
||||
end
|
||||
else
|
||||
{:error, dgettext("errors", "Profile is not member of group")}
|
||||
end
|
||||
|
||||
nil ->
|
||||
{:error, dgettext("errors", "Resource doesn't exist")}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -156,6 +173,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:error, dgettext("errors", "You need to be logged-in to update resources")}
|
||||
end
|
||||
|
||||
@spec delete_resource(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Resource.t()} | {:error, String.t()}
|
||||
def delete_resource(
|
||||
_parent,
|
||||
%{id: resource_id},
|
||||
@@ -169,7 +188,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:resource, Resources.get_resource_with_preloads(resource_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Resource{} = resource} <-
|
||||
ActivityPub.delete(resource, actor) do
|
||||
Actions.Delete.delete(resource, actor) do
|
||||
{:ok, resource}
|
||||
else
|
||||
{:resource, _} ->
|
||||
@@ -184,6 +203,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:error, dgettext("errors", "You need to be logged-in to delete resources")}
|
||||
end
|
||||
|
||||
@spec preview_resource_link(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Metadata.t()} | {:error, String.t() | :unknown_resource}
|
||||
def preview_resource_link(
|
||||
_parent,
|
||||
%{resource_url: resource_url},
|
||||
@@ -211,6 +232,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
||||
{:error, dgettext("errors", "You need to be logged-in to view a resource preview")}
|
||||
end
|
||||
|
||||
@spec proxyify_pictures(Metadata.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, String.t() | nil} | {:error, String.t()}
|
||||
def proxyify_pictures(%Metadata{} = metadata, _args, %{
|
||||
definition: %{schema_node: %{name: name}}
|
||||
}) do
|
||||
|
||||
@@ -2,12 +2,16 @@ defmodule Mobilizon.GraphQL.Resolvers.Search do
|
||||
@moduledoc """
|
||||
Handles the event-related GraphQL calls
|
||||
"""
|
||||
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.GraphQL.API.Search
|
||||
alias Mobilizon.Storage.Page
|
||||
|
||||
@doc """
|
||||
Search persons
|
||||
"""
|
||||
@spec search_persons(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Actor.t())} | {:error, String.t()}
|
||||
def search_persons(_parent, %{page: page, limit: limit} = args, _resolution) do
|
||||
Search.search_actors(Map.put(args, :minimum_visibility, :private), page, limit, :Person)
|
||||
end
|
||||
@@ -15,6 +19,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Search do
|
||||
@doc """
|
||||
Search groups
|
||||
"""
|
||||
@spec search_groups(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Actor.t())} | {:error, String.t()}
|
||||
def search_groups(_parent, %{page: page, limit: limit} = args, _resolution) do
|
||||
Search.search_actors(args, page, limit, :Group)
|
||||
end
|
||||
@@ -22,10 +28,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Search do
|
||||
@doc """
|
||||
Search events
|
||||
"""
|
||||
@spec search_events(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Event.t())} | {:error, String.t()}
|
||||
def search_events(_parent, %{page: page, limit: limit} = args, _resolution) do
|
||||
Search.search_events(args, page, limit)
|
||||
end
|
||||
|
||||
@spec interact(any(), map(), Absinthe.Resolution.t()) :: {:ok, struct} | {:error, :not_found}
|
||||
def interact(_parent, %{uri: uri}, _resolution) do
|
||||
Search.interact(uri)
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Statistics do
|
||||
@doc """
|
||||
Gets config.
|
||||
"""
|
||||
@spec get_statistics(any(), any(), any()) :: {:ok, map()}
|
||||
def get_statistics(_parent, _params, _context) do
|
||||
{:ok,
|
||||
%{
|
||||
|
||||
@@ -6,7 +6,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
alias Mobilizon.{Events, Posts}
|
||||
alias Mobilizon.Events.{Event, Tag}
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Storage.Page
|
||||
|
||||
@spec list_tags(any(), map(), Absinthe.Resolution.t()) :: {:ok, Page.t(Tag.t())}
|
||||
def list_tags(_parent, %{page: page, limit: limit} = args, _resolution) do
|
||||
filter = Map.get(args, :filter)
|
||||
tags = Mobilizon.Events.list_tags(filter, page, limit)
|
||||
@@ -19,6 +21,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
|
||||
From an event or a struct with an url
|
||||
"""
|
||||
@spec list_tags_for_event(Event.t(), map(), Absinthe.Resolution.t()) :: {:ok, list(Tag.t())}
|
||||
def list_tags_for_event(%Event{id: id}, _args, _resolution) do
|
||||
{:ok, Events.list_tags_for_event(id)}
|
||||
end
|
||||
@@ -33,6 +36,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
@doc """
|
||||
Retrieve the list of tags for a post
|
||||
"""
|
||||
@spec list_tags_for_post(Post.t(), map(), Absinthe.Resolution.t()) :: {:ok, list(Tag.t())}
|
||||
def list_tags_for_post(%Post{id: id}, _args, _resolution) do
|
||||
{:ok, Posts.list_tags_for_post(id)}
|
||||
end
|
||||
@@ -50,9 +54,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Tag do
|
||||
@doc """
|
||||
Retrieve the list of related tags for a parent tag
|
||||
"""
|
||||
@spec list_tags_for_post(Tag.t(), map(), Absinthe.Resolution.t()) :: {:ok, list(Tag.t())}
|
||||
def get_related_tags(%Tag{} = tag, _args, _resolution) do
|
||||
with tags <- Events.list_tag_neighbors(tag) do
|
||||
{:ok, tags}
|
||||
end
|
||||
{:ok, Events.list_tag_neighbors(tag)}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
|
||||
alias Mobilizon.{Actors, Todos}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Actions
|
||||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Todos.{Todo, TodoList}
|
||||
import Mobilizon.Web.Gettext
|
||||
@@ -17,6 +17,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
|
||||
Returns only if actor requesting is a member of the group
|
||||
"""
|
||||
@spec find_todo_lists_for_group(Actor.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(TodoList.t())}
|
||||
def find_todo_lists_for_group(
|
||||
%Actor{id: group_id} = group,
|
||||
_args,
|
||||
@@ -39,6 +41,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
{:ok, %Page{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
@spec find_todo_lists_for_group(TodoList.t(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Todo.t())} | {:error, String.t()}
|
||||
def find_todos_for_todo_list(
|
||||
%TodoList{actor_id: group_id} = todo_list,
|
||||
_args,
|
||||
@@ -55,6 +59,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_todo_list(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, TodoList.t()} | {:error, String.t()}
|
||||
def get_todo_list(
|
||||
_parent,
|
||||
%{id: todo_list_id},
|
||||
@@ -78,6 +84,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
end
|
||||
end
|
||||
|
||||
@spec create_todo_list(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, TodoList.t()} | {:error, String.t()}
|
||||
def create_todo_list(
|
||||
_parent,
|
||||
%{group_id: group_id} = args,
|
||||
@@ -87,7 +95,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %TodoList{} = todo_list} <-
|
||||
ActivityPub.create(:todo_list, Map.put(args, :actor_id, group_id), true, %{}) do
|
||||
Actions.Create.create(
|
||||
:todo_list,
|
||||
Map.put(args, :actor_id, group_id),
|
||||
true,
|
||||
%{}
|
||||
) do
|
||||
{:ok, todo_list}
|
||||
else
|
||||
{:actor, nil} ->
|
||||
@@ -110,7 +123,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
# {:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
# {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
# {:ok, _, %TodoList{} = todo} <-
|
||||
# ActivityPub.update_todo_list(todo_list, actor, true, %{}) do
|
||||
# Actions.Update.update_todo_list(todo_list, actor, true, %{}) do
|
||||
# {:ok, todo}
|
||||
# else
|
||||
# {:todo_list, _} ->
|
||||
@@ -133,7 +146,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
# {:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
# {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
# {:ok, _, %TodoList{} = todo} <-
|
||||
# ActivityPub.delete_todo_list(todo_list, actor, true, %{}) do
|
||||
# Actions.Delete.delete_todo_list(todo_list, actor, true, %{}) do
|
||||
# {:ok, todo}
|
||||
# else
|
||||
# {:todo_list, _} ->
|
||||
@@ -144,6 +157,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
# end
|
||||
# end
|
||||
|
||||
@spec get_todo(any(), map(), Absinthe.Resolution.t()) :: {:ok, Todo.t()} | {:error, String.t()}
|
||||
def get_todo(
|
||||
_parent,
|
||||
%{id: todo_id},
|
||||
@@ -169,6 +183,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
end
|
||||
end
|
||||
|
||||
@spec create_todo(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Todo.t()} | {:error, String.t()}
|
||||
def create_todo(
|
||||
_parent,
|
||||
%{todo_list_id: todo_list_id} = args,
|
||||
@@ -180,7 +196,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
{:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Todo{} = todo} <-
|
||||
ActivityPub.create(:todo, Map.put(args, :creator_id, actor_id), true, %{}) do
|
||||
Actions.Create.create(
|
||||
:todo,
|
||||
Map.put(args, :creator_id, actor_id),
|
||||
true,
|
||||
%{}
|
||||
) do
|
||||
{:ok, todo}
|
||||
else
|
||||
{:actor, nil} ->
|
||||
@@ -194,6 +215,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
end
|
||||
end
|
||||
|
||||
@spec update_todo(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Todo.t()} | {:error, String.t()}
|
||||
def update_todo(
|
||||
_parent,
|
||||
%{id: todo_id} = args,
|
||||
@@ -207,7 +230,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
{:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:ok, _, %Todo{} = todo} <-
|
||||
ActivityPub.update(todo, args, true, %{}) do
|
||||
Actions.Update.update(todo, args, true, %{}) do
|
||||
{:ok, todo}
|
||||
else
|
||||
{:actor, nil} ->
|
||||
@@ -238,7 +261,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
||||
# {:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
# {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
# {:ok, _, %Todo{} = todo} <-
|
||||
# ActivityPub.delete_todo(todo, actor, true, %{}) do
|
||||
# Actions.Delete.delete_todo(todo, actor, true, %{}) do
|
||||
# {:ok, todo}
|
||||
# else
|
||||
# {:todo_list, _} ->
|
||||
|
||||
@@ -7,8 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
|
||||
alias Mobilizon.{Actors, Admin, Config, Events, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Relay}
|
||||
alias Mobilizon.Service.Auth.Authenticator
|
||||
alias Mobilizon.Storage.{Page, Repo}
|
||||
alias Mobilizon.Users.{Setting, User}
|
||||
@@ -21,6 +20,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
@doc """
|
||||
Find an user by its ID
|
||||
"""
|
||||
@spec find_user(any(), map(), Absinthe.Resolution.t()) :: {:ok, User.t()} | {:error, String.t()}
|
||||
def find_user(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
|
||||
when is_moderator(role) do
|
||||
with {:ok, %User{} = user} <- Users.get_user_with_actors(id) do
|
||||
@@ -44,6 +44,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
@doc """
|
||||
List instance users
|
||||
"""
|
||||
@spec list_users(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(User.t())} | {:error, :unauthorized}
|
||||
def list_users(
|
||||
_parent,
|
||||
%{email: email, page: page, limit: limit, sort: sort, direction: direction},
|
||||
@@ -60,6 +62,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
@doc """
|
||||
Login an user. Returns a token and the user
|
||||
"""
|
||||
@spec login_user(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, map()} | {:error, :user_not_found | String.t()}
|
||||
def login_user(_parent, %{email: email, password: password}, %{context: context}) do
|
||||
with {:ok,
|
||||
%{
|
||||
@@ -88,6 +92,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
@doc """
|
||||
Refresh a token
|
||||
"""
|
||||
@spec refresh_token(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, map()} | {:error, String.t()}
|
||||
def refresh_token(_parent, %{refresh_token: refresh_token}, _resolution) do
|
||||
with {:ok, user, _claims} <- Auth.Guardian.resource_from_token(refresh_token),
|
||||
{:ok, _old, {exchanged_token, _claims}} <-
|
||||
@@ -106,6 +112,9 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
{:error, dgettext("errors", "You need to have an existing token to get a refresh token")}
|
||||
end
|
||||
|
||||
@spec logout(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, String.t()}
|
||||
| {:error, :token_not_found | :unable_to_logout | :unauthenticated | :invalid_argument}
|
||||
def logout(_parent, %{refresh_token: refresh_token}, %{context: %{current_user: %User{}}}) do
|
||||
with {:ok, _claims} <- Auth.Guardian.decode_and_verify(refresh_token, %{"typ" => "refresh"}),
|
||||
{:ok, _claims} <- Auth.Guardian.revoke(refresh_token) do
|
||||
@@ -134,7 +143,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
- create the user
|
||||
- send a validation email to the user
|
||||
"""
|
||||
@spec create_user(any, %{email: String.t()}, any) :: tuple
|
||||
@spec create_user(any, %{email: String.t()}, any) :: {:ok, User.t()} | {:error, String.t()}
|
||||
def create_user(_parent, %{email: email} = args, _resolution) do
|
||||
with :registration_ok <- check_registration_config(email),
|
||||
:not_deny_listed <- check_registration_denylist(email),
|
||||
@@ -161,7 +170,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
end
|
||||
end
|
||||
|
||||
@spec check_registration_config(String.t()) :: atom
|
||||
@spec check_registration_config(String.t()) ::
|
||||
:registration_ok | :registration_closed | :not_allowlisted
|
||||
defp check_registration_config(email) do
|
||||
cond do
|
||||
Config.instance_registrations_open?() ->
|
||||
@@ -523,7 +533,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
:ok <-
|
||||
Enum.each(actors, fn actor ->
|
||||
actor_performing = Keyword.get(options, :actor_performing, actor)
|
||||
ActivityPub.delete(actor, actor_performing, true)
|
||||
Actions.Delete.delete(actor, actor_performing, true)
|
||||
end),
|
||||
# Delete user
|
||||
{:ok, user} <-
|
||||
|
||||
@@ -4,10 +4,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Users.ActivitySettings do
|
||||
"""
|
||||
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Users.User
|
||||
alias Mobilizon.Users.{ActivitySetting, User}
|
||||
|
||||
require Logger
|
||||
|
||||
@spec user_activity_settings(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, list(ActivitySetting.t())} | {:error, :unauthenticated}
|
||||
def user_activity_settings(_parent, _args, %{context: %{current_user: %User{} = user}}) do
|
||||
{:ok, Users.activity_settings_for_user(user)}
|
||||
end
|
||||
@@ -16,6 +18,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Users.ActivitySettings do
|
||||
{:error, :unauthenticated}
|
||||
end
|
||||
|
||||
@spec upsert_user_activity_setting(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, ActivitySetting.t()} | {:error, :unauthenticated}
|
||||
def upsert_user_activity_setting(_parent, args, %{context: %{current_user: %User{id: user_id}}}) do
|
||||
Users.create_activity_setting(Map.put(args, :user_id, user_id))
|
||||
end
|
||||
|
||||
@@ -194,6 +194,7 @@ defmodule Mobilizon.GraphQL.Schema do
|
||||
import_fields(:discussion_subscriptions)
|
||||
end
|
||||
|
||||
@spec middleware(list(module()), any(), map()) :: list(module())
|
||||
def middleware(middleware, _field, %{identifier: type}) when type in [:query, :mutation] do
|
||||
[CurrentActorProvider] ++ middleware ++ [ErrorHandler]
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user