diff options
Diffstat (limited to 'lib/mix/tasks/pleroma/user.ex')
-rw-r--r-- | lib/mix/tasks/pleroma/user.ex | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex new file mode 100644 index 000000000..c20fecaa1 --- /dev/null +++ b/lib/mix/tasks/pleroma/user.ex @@ -0,0 +1,207 @@ +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 |