Add a CLI command to delete actors
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
110
lib/mix/tasks/mobilizon/actors/delete.ex
Normal file
110
lib/mix/tasks/mobilizon/actors/delete.ex
Normal file
@@ -0,0 +1,110 @@
|
||||
defmodule Mix.Tasks.Mobilizon.Actors.Delete do
|
||||
@moduledoc """
|
||||
Task to delete an actor
|
||||
"""
|
||||
use Mix.Task
|
||||
alias Mobilizon.{Actors, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Service.ActorSuspension
|
||||
alias Mobilizon.Users.User
|
||||
import Mix.Tasks.Mobilizon.Common
|
||||
|
||||
@shortdoc "Deletes a Mobilizon person or a group"
|
||||
|
||||
@impl Mix.Task
|
||||
def run([federated_username | rest]) do
|
||||
{options, [], []} =
|
||||
OptionParser.parse(
|
||||
rest,
|
||||
strict: [
|
||||
assume_yes: :boolean,
|
||||
keep_username: :boolean
|
||||
],
|
||||
aliases: [
|
||||
y: :assume_yes,
|
||||
k: :keep_username
|
||||
]
|
||||
)
|
||||
|
||||
assume_yes? = Keyword.get(options, :assume_yes, false)
|
||||
keep_username? = Keyword.get(options, :keep_username, false)
|
||||
|
||||
start_mobilizon()
|
||||
|
||||
# To make sure we can delete actors created by mistake with "@" in their username
|
||||
case Actors.get_local_actor_by_name(federated_username) ||
|
||||
Actors.get_actor_by_name(federated_username) do
|
||||
%Actor{preferred_username: username, domain: nil} when username in ["relay", "anonymous"] ->
|
||||
shell_error("This actor can't be deleted.")
|
||||
|
||||
%Actor{} = actor ->
|
||||
if check_everything(actor, assume_yes?) do
|
||||
ActorSuspension.suspend_actor(actor,
|
||||
reserve_username: keep_username?,
|
||||
suspension: false
|
||||
)
|
||||
|
||||
display_name = Actor.display_name_and_username(actor)
|
||||
|
||||
shell_info("""
|
||||
The actor #{display_name} has been deleted
|
||||
""")
|
||||
else
|
||||
shell_error("Actor has not been deleted.")
|
||||
end
|
||||
|
||||
nil ->
|
||||
shell_error("No actor found with this username")
|
||||
end
|
||||
end
|
||||
|
||||
def run(_) do
|
||||
shell_error(
|
||||
"mobilizon.actors.delete requires an username or a federated username as argument"
|
||||
)
|
||||
end
|
||||
|
||||
@spec check_everything(Actor.t(), boolean()) :: boolean()
|
||||
defp check_everything(%Actor{} = actor, assume_yes?) do
|
||||
display_name = Actor.display_name_and_username(actor)
|
||||
|
||||
(assume_yes? or
|
||||
shell_yes?(
|
||||
"All content by this profile or group will be deleted. Continue with deleting #{display_name}?"
|
||||
)) and
|
||||
check_actor(actor, assume_yes?)
|
||||
end
|
||||
|
||||
@spec check_actor(Actor.t(), boolean()) :: boolean()
|
||||
defp check_actor(%Actor{type: :Group} = group, assume_yes?) do
|
||||
display_name = Actor.display_name_and_username(group)
|
||||
nb_members = Actors.count_members_for_group(group)
|
||||
nb_followers = Actors.count_followers_for_actor(group)
|
||||
|
||||
if nb_followers + nb_members > 0 do
|
||||
shell_info("Group members will be notified of the group deletion.")
|
||||
|
||||
assume_yes? or
|
||||
shell_yes?(
|
||||
"Group #{display_name} has #{nb_members} members and #{nb_followers} followers. Continue deleting?"
|
||||
)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
defp check_actor(%Actor{type: :Person, domain: nil} = profile, assume_yes?) do
|
||||
%User{actors: actors, email: email} = Users.get_user_with_actors!(profile.user_id)
|
||||
|
||||
if length(actors) == 1 do
|
||||
assume_yes? or
|
||||
shell_yes?(
|
||||
"This profile is the only one user #{email} has. Mobilizon will invite the user to create a new profile on their next login. If you want to remove the whole user account, use the `mobilizon.users.delete` command. Continue deleting?"
|
||||
)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
defp check_actor(%Actor{} = _actor, assume_yes?), do: assume_yes?
|
||||
end
|
||||
Reference in New Issue
Block a user