diff options
Diffstat (limited to 'lib/mix')
| -rw-r--r-- | lib/mix/pleroma.ex | 15 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/benchmark.ex | 2 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/config.ex | 158 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/database.ex | 2 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/docs.ex | 2 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/ecto/ecto.ex | 2 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/ecto/migrate.ex | 2 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/ecto/rollback.ex | 2 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/email.ex | 24 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/emoji.ex | 10 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/instance.ex | 17 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/notification_settings.ex | 83 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/refresh_counter_cache.ex | 46 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/relay.ex | 4 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/robotstxt.ex | 3 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/uploads.ex | 2 | ||||
| -rw-r--r-- | lib/mix/tasks/pleroma/user.ex | 20 | 
17 files changed, 321 insertions, 73 deletions
| diff --git a/lib/mix/pleroma.ex b/lib/mix/pleroma.ex index 73a076a53..3ad6edbfb 100644 --- a/lib/mix/pleroma.ex +++ b/lib/mix/pleroma.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Pleroma do @@ -12,6 +12,19 @@ defmodule Mix.Pleroma do      end      {:ok, _} = Application.ensure_all_started(:pleroma) + +    if Pleroma.Config.get(:env) not in [:test, :benchmark] do +      pleroma_rebooted?() +    end +  end + +  defp pleroma_rebooted? do +    if Restarter.Pleroma.rebooted?() do +      :ok +    else +      Process.sleep(10) +      pleroma_rebooted?() +    end    end    def load_pleroma do diff --git a/lib/mix/tasks/pleroma/benchmark.ex b/lib/mix/tasks/pleroma/benchmark.ex index 84dccf7f3..a4885b70c 100644 --- a/lib/mix/tasks/pleroma/benchmark.ex +++ b/lib/mix/tasks/pleroma/benchmark.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.Benchmark do diff --git a/lib/mix/tasks/pleroma/config.ex b/lib/mix/tasks/pleroma/config.ex index 0e21408b2..5c9ef6904 100644 --- a/lib/mix/tasks/pleroma/config.ex +++ b/lib/mix/tasks/pleroma/config.ex @@ -1,72 +1,150 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.Config do    use Mix.Task +    import Mix.Pleroma + +  alias Pleroma.ConfigDB    alias Pleroma.Repo -  alias Pleroma.Web.AdminAPI.Config +    @shortdoc "Manages the location of the config"    @moduledoc File.read!("docs/administration/CLI_tasks/config.md") +    def run(["migrate_to_db"]) do      start_pleroma() +    migrate_to_db() +  end + +  def run(["migrate_from_db" | options]) do +    start_pleroma() -    if Pleroma.Config.get([:instance, :dynamic_configuration]) do -      Application.get_all_env(:pleroma) -      |> Enum.reject(fn {k, _v} -> k in [Pleroma.Repo, :env] end) -      |> Enum.each(fn {k, v} -> -        key = to_string(k) |> String.replace("Elixir.", "") +    {opts, _} = +      OptionParser.parse!(options, +        strict: [env: :string, delete: :boolean], +        aliases: [d: :delete] +      ) + +    migrate_from_db(opts) +  end -        key = -          if String.starts_with?(key, "Pleroma.") do -            key +  @spec migrate_to_db(Path.t() | nil) :: any() +  def migrate_to_db(file_path \\ nil) do +    if Pleroma.Config.get([:configurable_from_database]) do +      config_file = +        if file_path do +          file_path +        else +          if Pleroma.Config.get(:release) do +            Pleroma.Config.get(:config_path)            else -            ":" <> key +            "config/#{Pleroma.Config.get(:env)}.secret.exs"            end +        end -        {:ok, _} = Config.update_or_create(%{group: "pleroma", key: key, value: v}) -        Mix.shell().info("#{key} is migrated.") -      end) - -      Mix.shell().info("Settings migrated.") +      do_migrate_to_db(config_file)      else -      Mix.shell().info( -        "Migration is not allowed by config. You can change this behavior in instance settings." -      ) +      migration_error()      end    end -  def run(["migrate_from_db", env, delete?]) do -    start_pleroma() +  defp do_migrate_to_db(config_file) do +    if File.exists?(config_file) do +      Ecto.Adapters.SQL.query!(Repo, "TRUNCATE config;") +      Ecto.Adapters.SQL.query!(Repo, "ALTER SEQUENCE config_id_seq RESTART;") -    delete? = if delete? == "true", do: true, else: false +      custom_config = +        config_file +        |> read_file() +        |> elem(0) -    if Pleroma.Config.get([:instance, :dynamic_configuration]) do -      config_path = "config/#{env}.exported_from_db.secret.exs" +      custom_config +      |> Keyword.keys() +      |> Enum.each(&create(&1, custom_config)) +    else +      shell_info("To migrate settings, you must define custom settings in #{config_file}.") +    end +  end -      {:ok, file} = File.open(config_path, [:write, :utf8]) -      IO.write(file, "use Mix.Config\r\n") +  defp create(group, settings) do +    group +    |> Pleroma.Config.Loader.filter_group(settings) +    |> Enum.each(fn {key, value} -> +      key = inspect(key) +      {:ok, _} = ConfigDB.update_or_create(%{group: inspect(group), key: key, value: value}) -      Repo.all(Config) -      |> Enum.each(fn config -> -        IO.write( -          file, -          "config :#{config.group}, #{config.key}, #{inspect(Config.from_binary(config.value))}\r\n\r\n" -        ) +      shell_info("Settings for key #{key} migrated.") +    end) + +    shell_info("Settings for group :#{group} migrated.") +  end -        if delete? do -          {:ok, _} = Repo.delete(config) -          Mix.shell().info("#{config.key} deleted from DB.") +  defp migrate_from_db(opts) do +    if Pleroma.Config.get([:configurable_from_database]) do +      env = opts[:env] || "prod" + +      config_path = +        if Pleroma.Config.get(:release) do +          :config_path +          |> Pleroma.Config.get() +          |> Path.dirname() +        else +          "config"          end -      end) +        |> Path.join("#{env}.exported_from_db.secret.exs") + +      file = File.open!(config_path, [:write, :utf8]) + +      IO.write(file, config_header()) -      File.close(file) +      ConfigDB +      |> Repo.all() +      |> Enum.each(&write_and_delete(&1, file, opts[:delete])) + +      :ok = File.close(file)        System.cmd("mix", ["format", config_path])      else -      Mix.shell().info( -        "Migration is not allowed by config. You can change this behavior in instance settings." -      ) +      migration_error()      end    end + +  defp migration_error do +    shell_error( +      "Migration is not allowed in config. You can change this behavior by setting `configurable_from_database` to true." +    ) +  end + +  if Code.ensure_loaded?(Config.Reader) do +    defp config_header, do: "import Config\r\n\r\n" +    defp read_file(config_file), do: Config.Reader.read_imports!(config_file) +  else +    defp config_header, do: "use Mix.Config\r\n\r\n" +    defp read_file(config_file), do: Mix.Config.eval!(config_file) +  end + +  defp write_and_delete(config, file, delete?) do +    config +    |> write(file) +    |> delete(delete?) +  end + +  defp write(config, file) do +    value = +      config.value +      |> ConfigDB.from_binary() +      |> inspect(limit: :infinity) + +    IO.write(file, "config #{config.group}, #{config.key}, #{value}\r\n\r\n") + +    config +  end + +  defp delete(config, true) do +    {:ok, _} = Repo.delete(config) +    shell_info("#{config.key} deleted from DB.") +  end + +  defp delete(_config, _), do: :ok  end diff --git a/lib/mix/tasks/pleroma/database.ex b/lib/mix/tasks/pleroma/database.ex index e2b5251bc..778de162f 100644 --- a/lib/mix/tasks/pleroma/database.ex +++ b/lib/mix/tasks/pleroma/database.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.Database do diff --git a/lib/mix/tasks/pleroma/docs.ex b/lib/mix/tasks/pleroma/docs.ex index 0d2663648..6088fc71d 100644 --- a/lib/mix/tasks/pleroma/docs.ex +++ b/lib/mix/tasks/pleroma/docs.ex @@ -28,7 +28,7 @@ defmodule Mix.Tasks.Pleroma.Docs do    defp do_run(implementation) do      start_pleroma() -    with {descriptions, _paths} <- Mix.Config.eval!("config/description.exs"), +    with descriptions <- Pleroma.Config.Loader.read("config/description.exs"),           {:ok, file_path} <-             Pleroma.Docs.Generator.process(               implementation, diff --git a/lib/mix/tasks/pleroma/ecto/ecto.ex b/lib/mix/tasks/pleroma/ecto/ecto.ex index 36808b93f..3363cd45f 100644 --- a/lib/mix/tasks/pleroma/ecto/ecto.ex +++ b/lib/mix/tasks/pleroma/ecto/ecto.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-onl  defmodule Mix.Tasks.Pleroma.Ecto do diff --git a/lib/mix/tasks/pleroma/ecto/migrate.ex b/lib/mix/tasks/pleroma/ecto/migrate.ex index d87b6957d..bc8ed29fb 100644 --- a/lib/mix/tasks/pleroma/ecto/migrate.ex +++ b/lib/mix/tasks/pleroma/ecto/migrate.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-onl  defmodule Mix.Tasks.Pleroma.Ecto.Migrate do diff --git a/lib/mix/tasks/pleroma/ecto/rollback.ex b/lib/mix/tasks/pleroma/ecto/rollback.ex index a1af73fa1..f43bd0b98 100644 --- a/lib/mix/tasks/pleroma/ecto/rollback.ex +++ b/lib/mix/tasks/pleroma/ecto/rollback.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-onl  defmodule Mix.Tasks.Pleroma.Ecto.Rollback do diff --git a/lib/mix/tasks/pleroma/email.ex b/lib/mix/tasks/pleroma/email.ex new file mode 100644 index 000000000..d3fac6ec8 --- /dev/null +++ b/lib/mix/tasks/pleroma/email.ex @@ -0,0 +1,24 @@ +defmodule Mix.Tasks.Pleroma.Email do +  use Mix.Task +  import Mix.Pleroma + +  @shortdoc "Simple Email test" +  @moduledoc File.read!("docs/administration/CLI_tasks/email.md") + +  def run(["test" | args]) do +    Mix.Pleroma.start_pleroma() + +    {options, [], []} = +      OptionParser.parse( +        args, +        strict: [ +          to: :string +        ] +      ) + +    email = Pleroma.Emails.AdminEmail.test_email(options[:to]) +    {:ok, _} = Pleroma.Emails.Mailer.deliver(email) + +    shell_info("Test email has been sent to #{inspect(email.to)} from #{inspect(email.from)}") +  end +end diff --git a/lib/mix/tasks/pleroma/emoji.ex b/lib/mix/tasks/pleroma/emoji.ex index 35669af27..2b03a3009 100644 --- a/lib/mix/tasks/pleroma/emoji.ex +++ b/lib/mix/tasks/pleroma/emoji.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.Emoji do @@ -9,6 +9,7 @@ defmodule Mix.Tasks.Pleroma.Emoji do    @moduledoc File.read!("docs/administration/CLI_tasks/emoji.md")    def run(["ls-packs" | args]) do +    Mix.Pleroma.start_pleroma()      Application.ensure_all_started(:hackney)      {options, [], []} = parse_global_opts(args) @@ -35,6 +36,7 @@ defmodule Mix.Tasks.Pleroma.Emoji do    end    def run(["get-packs" | args]) do +    Mix.Pleroma.start_pleroma()      Application.ensure_all_started(:hackney)      {options, pack_names, []} = parse_global_opts(args) @@ -184,11 +186,7 @@ defmodule Mix.Tasks.Pleroma.Emoji do      tmp_pack_dir = Path.join(System.tmp_dir!(), "emoji-pack-#{name}") -    {:ok, _} = -      :zip.unzip( -        binary_archive, -        cwd: tmp_pack_dir -      ) +    {:ok, _} = :zip.unzip(binary_archive, cwd: String.to_charlist(tmp_pack_dir))      emoji_map = Pleroma.Emoji.Loader.make_shortcode_to_file_map(tmp_pack_dir, exts) diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex index 9af6cda30..bc842a59f 100644 --- a/lib/mix/tasks/pleroma/instance.ex +++ b/lib/mix/tasks/pleroma/instance.ex @@ -1,11 +1,13 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.Instance do    use Mix.Task    import Mix.Pleroma +  alias Pleroma.Config +    @shortdoc "Manages Pleroma instance"    @moduledoc File.read!("docs/administration/CLI_tasks/instance.md") @@ -63,7 +65,8 @@ defmodule Mix.Tasks.Pleroma.Instance do          get_option(            options,            :instance_name, -          "What is the name of your instance? (e.g. Pleroma/Soykaf)" +          "What is the name of your instance? (e.g. The Corndog Emporium)", +          domain          )        email = get_option(options, :admin_email, "What is your admin email address?") @@ -153,6 +156,8 @@ defmodule Mix.Tasks.Pleroma.Instance do            Pleroma.Config.get([:instance, :static_dir])          ) +      Config.put([:instance, :static_dir], static_dir) +        secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)        jwt_secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)        signing_salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8) @@ -202,8 +207,14 @@ defmodule Mix.Tasks.Pleroma.Instance do        write_robots_txt(indexable, template_dir)        shell_info( -        "\n All files successfully written! Refer to the installation instructions for your platform for next steps" +        "\n All files successfully written! Refer to the installation instructions for your platform for next steps."        ) + +      if db_configurable? do +        shell_info( +          " Please transfer your config to the database after running database migrations. Refer to \"Transfering the config to/from the database\" section of the docs for more information." +        ) +      end      else        shell_error(          "The task would have overwritten the following files:\n" <> diff --git a/lib/mix/tasks/pleroma/notification_settings.ex b/lib/mix/tasks/pleroma/notification_settings.ex new file mode 100644 index 000000000..7d65f0587 --- /dev/null +++ b/lib/mix/tasks/pleroma/notification_settings.ex @@ -0,0 +1,83 @@ +defmodule Mix.Tasks.Pleroma.NotificationSettings do +  @shortdoc "Enable&Disable privacy option for push notifications" +  @moduledoc """ +  Example: + +  > mix pleroma.notification_settings --privacy-option=false --nickname-users="parallel588"  # set false only for parallel588 user +  > mix pleroma.notification_settings --privacy-option=true # set true for all users + +  """ + +  use Mix.Task +  import Mix.Pleroma +  import Ecto.Query + +  def run(args) do +    start_pleroma() + +    {options, _, _} = +      OptionParser.parse( +        args, +        strict: [ +          privacy_option: :boolean, +          email_users: :string, +          nickname_users: :string +        ] +      ) + +    privacy_option = Keyword.get(options, :privacy_option) + +    if not is_nil(privacy_option) do +      privacy_option +      |> build_query(options) +      |> Pleroma.Repo.update_all([]) +    end + +    shell_info("Done") +  end + +  defp build_query(privacy_option, options) do +    query = +      from(u in Pleroma.User, +        update: [ +          set: [ +            notification_settings: +              fragment( +                "jsonb_set(notification_settings, '{privacy_option}', ?)", +                ^privacy_option +              ) +          ] +        ] +      ) + +    user_emails = +      options +      |> Keyword.get(:email_users, "") +      |> String.split(",") +      |> Enum.map(&String.trim(&1)) +      |> Enum.reject(&(&1 == "")) + +    query = +      if length(user_emails) > 0 do +        where(query, [u], u.email in ^user_emails) +      else +        query +      end + +    user_nicknames = +      options +      |> Keyword.get(:nickname_users, "") +      |> String.split(",") +      |> Enum.map(&String.trim(&1)) +      |> Enum.reject(&(&1 == "")) + +    query = +      if length(user_nicknames) > 0 do +        where(query, [u], u.nickname in ^user_nicknames) +      else +        query +      end + +    query +  end +end diff --git a/lib/mix/tasks/pleroma/refresh_counter_cache.ex b/lib/mix/tasks/pleroma/refresh_counter_cache.ex new file mode 100644 index 000000000..15b4dbfa6 --- /dev/null +++ b/lib/mix/tasks/pleroma/refresh_counter_cache.ex @@ -0,0 +1,46 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Mix.Tasks.Pleroma.RefreshCounterCache do +  @shortdoc "Refreshes counter cache" + +  use Mix.Task + +  alias Pleroma.Activity +  alias Pleroma.CounterCache +  alias Pleroma.Repo + +  require Logger +  import Ecto.Query + +  def run([]) do +    Mix.Pleroma.start_pleroma() + +    ["public", "unlisted", "private", "direct"] +    |> Enum.each(fn visibility -> +      count = status_visibility_count_query(visibility) +      name = "status_visibility_#{visibility}" +      CounterCache.set(name, count) +      Mix.Pleroma.shell_info("Set #{name} to #{count}") +    end) + +    Mix.Pleroma.shell_info("Done") +  end + +  defp status_visibility_count_query(visibility) do +    Activity +    |> where( +      [a], +      fragment( +        "activity_visibility(?, ?, ?) = ?", +        a.actor, +        a.recipients, +        a.data, +        ^visibility +      ) +    ) +    |> where([a], fragment("(? ->> 'type'::text) = 'Create'", a.data)) +    |> Repo.aggregate(:count, :id, timeout: :timer.minutes(30)) +  end +end diff --git a/lib/mix/tasks/pleroma/relay.ex b/lib/mix/tasks/pleroma/relay.ex index 7ef5f9678..c3312507e 100644 --- a/lib/mix/tasks/pleroma/relay.ex +++ b/lib/mix/tasks/pleroma/relay.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.Relay do @@ -35,7 +35,7 @@ defmodule Mix.Tasks.Pleroma.Relay do    def run(["list"]) do      start_pleroma() -    with {:ok, list} <- Relay.list() do +    with {:ok, list} <- Relay.list(true) do        list |> Enum.each(&shell_info(&1))      else        {:error, e} -> shell_error("Error while fetching relay subscription list: #{inspect(e)}") diff --git a/lib/mix/tasks/pleroma/robotstxt.ex b/lib/mix/tasks/pleroma/robotstxt.ex index 2128e1cd6..24f08180e 100644 --- a/lib/mix/tasks/pleroma/robotstxt.ex +++ b/lib/mix/tasks/pleroma/robotstxt.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.RobotsTxt do @@ -18,6 +18,7 @@ defmodule Mix.Tasks.Pleroma.RobotsTxt do    """    def run(["disallow_all"]) do +    Mix.Pleroma.start_pleroma()      static_dir = Pleroma.Config.get([:instance, :static_dir], "instance/static/")      if !File.exists?(static_dir) do diff --git a/lib/mix/tasks/pleroma/uploads.ex b/lib/mix/tasks/pleroma/uploads.ex index 3e6fc7ee0..c47b7531e 100644 --- a/lib/mix/tasks/pleroma/uploads.ex +++ b/lib/mix/tasks/pleroma/uploads.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.Uploads do diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index bc8eacda8..40dd9bdc0 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.User do @@ -8,7 +8,6 @@ defmodule Mix.Tasks.Pleroma.User do    alias Ecto.Changeset    alias Pleroma.User    alias Pleroma.UserInviteToken -  alias Pleroma.Web.OAuth    @shortdoc "Manages Pleroma users"    @moduledoc File.read!("docs/administration/CLI_tasks/user.md") @@ -101,8 +100,7 @@ defmodule Mix.Tasks.Pleroma.User do        User.perform(:delete, user)        shell_info("User #{nickname} deleted.")      else -      _ -> -        shell_error("No local user #{nickname}") +      _ -> shell_error("No local user #{nickname}")      end    end @@ -354,8 +352,7 @@ defmodule Mix.Tasks.Pleroma.User do      start_pleroma()      with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do -      OAuth.Token.delete_user_tokens(user) -      OAuth.Authorization.delete_user_authorizations(user) +      User.global_sign_out(user)        shell_info("#{nickname} signed out from all apps.")      else @@ -373,9 +370,9 @@ defmodule Mix.Tasks.Pleroma.User do        users        |> Enum.each(fn user ->          shell_info( -          "#{user.nickname} moderator: #{user.info.is_moderator}, admin: #{user.info.is_admin}, locked: #{ -            user.info.locked -          }, deactivated: #{user.info.deactivated}" +          "#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{ +            user.locked +          }, deactivated: #{user.deactivated}"          )        end)      end) @@ -393,10 +390,7 @@ defmodule Mix.Tasks.Pleroma.User do    end    defp set_admin(user, value) do -    {:ok, user} = -      user -      |> Changeset.change(%{is_admin: value}) -      |> User.update_and_set_cache() +    {:ok, user} = User.admin_api_update(user, %{is_admin: value})      shell_info("Admin status of #{user.nickname}: #{user.is_admin}")      user | 
