akkoma/lib/mix/tasks/pleroma/user.ex
Jorty 8a1dc0de92 Refactor Mix tasks
1. Move Mix tasks into a `pleroma` namespace, to avoid
   collisions with dependent packages.

2. Rename and condense tasks  into two `pleroma.user` and
   `pleroma.gen.instance` tasks for consistency with Hex and Phoenix.

3. Add additional functionality to the tasks to make them more
   user-friendly. Arguments with sensible defaults were demoted to flags
   and in the interactive `generate_config` (renamed to
   `pleroma.gen.instance`), flags were added to allow non-interactive
   use, though interactive use remains the primary interface. That task
   also now prompts the user for database parameters.

4. Documentation has been added to both tasks such that `mix help` now
   shows useful information.

5. Finally, use of IO.puts in tasks has been replaced with Mix.shell()
   equivalents to make the behavior more consistent with Mix tasks in
   other packages, and such that variables like MIX_QUIET are respected.
   The only exception is in `mix pleroma.user reset_password`, wherein
   the URL must always be printed regardless of the value of MIX_QUIET
   since that's its entire purpose.
2018-08-23 11:33:16 -04:00

208 lines
4.9 KiB
Elixir

defmodule Mix.Tasks.Pleroma.User do
use Mix.Task
alias Pleroma.{Repo, User}
@shortdoc "Manages Pleroma users"
@moduledoc """
Manages Pleroma users.
## Create a new user.
mix pleroma.user new NICKNAME EMAIL [OPTION...]
Options:
- `--name NAME` - the user's name (i.e., "Lain Iwakura")
- `--bio BIO` - the user's bio
- `--password PASSWORD` - the user's password
- `--moderator`/`--no-moderator` - whether the user is a moderator
## Delete the user's account.
mix pleroma.user rm NICKNAME
## Deactivate or activate the user's account.
mix pleroma.user toggle_activated NICKNAME
## Create a password reset link.
mix pleroma.user reset_password NICKNAME
## Set the value of the given user's settings.
mix pleroma.user set NICKNAME [OPTION...]
Options:
- `--locked`/`--no-locked` - whether the user's account is locked
- `--moderator`/`--no-moderator` - whether the user is a moderator
"""
def run(["new", nickname, email | rest]) do
{options, [], []} =
OptionParser.parse(
rest,
strict: [
name: :string,
bio: :string,
password: :string,
moderator: :boolean
]
)
name = Keyword.get(options, :name, nickname)
bio = Keyword.get(options, :bio, "")
{password, generated_password?} =
case Keyword.get(options, :password) do
nil ->
{:crypto.strong_rand_bytes(16) |> Base.encode64(), true}
password ->
{password, false}
end
moderator? = Keyword.get(options, :moderator, false)
Mix.shell().info("""
A user will be created with the following information:
- nickname: #{nickname}
- email: #{email}
- password: #{
if(generated_password?, do: "[generated; a reset link will be created]", else: password)
}
- name: #{name}
- bio: #{bio}
- moderator: #{if(moderator?, do: "true", else: "false")}
""")
proceed? = Mix.shell().yes?("Continue?")
unless not proceed? do
Mix.Task.run("app.start")
params =
%{
nickname: nickname,
email: email,
password: password,
password_confirmation: password,
name: name,
bio: bio
}
|> IO.inspect()
user = User.register_changeset(%User{}, params)
Repo.insert!(user)
Mix.shell().info("User #{nickname} created")
if moderator? do
run(["set", nickname, "--moderator"])
end
if generated_password? do
run(["reset_password", nickname])
end
else
Mix.shell().info("User will not be created.")
end
end
def run(["rm", nickname]) do
Mix.Task.run("app.start")
with %User{local: true} = user <- User.get_by_nickname(nickname) do
User.delete(user)
end
Mix.shell().info("User #{nickname} deleted.")
end
def run(["toggle_activated", nickname]) do
Mix.Task.run("app.start")
with user <- User.get_by_nickname(nickname) do
User.deactivate(user)
end
end
def run(["reset_password", nickname]) do
Mix.Task.run("app.start")
with %User{local: true} = user <- User.get_by_nickname(nickname),
{:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do
Mix.shell().info("Generated password reset token for #{user.nickname}")
IO.puts(
"URL: #{
Pleroma.Web.Router.Helpers.util_url(
Pleroma.Web.Endpoint,
:show_password_reset,
token.token
)
}"
)
else
_ ->
Mix.shell().error("No local user #{nickname}")
end
end
def run(["set", nickname | rest]) do
{options, [], []} =
OptionParser.parse(
rest,
strict: [
moderator: :boolean,
locked: :boolean
]
)
case Keyword.get(options, :moderator) do
nil -> nil
value -> set_moderator(nickname, value)
end
case Keyword.get(options, :locked) do
nil -> nil
value -> set_locked(nickname, value)
end
end
defp set_moderator(nickname, value) do
Application.ensure_all_started(:pleroma)
with %User{local: true} = user <- User.get_by_nickname(nickname) do
info =
user.info
|> Map.put("is_moderator", value)
cng = User.info_changeset(user, %{info: info})
{:ok, user} = User.update_and_set_cache(cng)
Mix.shell().info("Moderator status of #{nickname}: #{user.info["is_moderator"]}")
else
_ ->
Mix.shell().error("No local user #{nickname}")
end
end
defp set_locked(nickname, value) do
Mix.Ecto.ensure_started(Repo, [])
with %User{local: true} = user <- User.get_by_nickname(nickname) do
info =
user.info
|> Map.put("locked", value)
cng = User.info_changeset(user, %{info: info})
user = Repo.update!(cng)
IO.puts("Locked status of #{nickname}: #{user.info["locked"]}")
else
_ ->
IO.puts("No local user #{nickname}")
end
end
end