X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fmix%2Ftasks%2Fpleroma%2Fuser.ex;h=09f9356d34998078a251870ca8e7b6630eb62ccd;hb=4a94c9a31ef11f63ea71ad9c1f085c18cf8ef083;hp=01824aa18b0f45dda65716d6189856f3394f63c1;hpb=79707e879d3af359be9e1f6ac10717cc9cb72b2c;p=akkoma diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index 01824aa18..dd1cdca5b 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-2020 Pleroma Authors +# Copyright © 2017-2021 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Mix.Tasks.Pleroma.User do @@ -7,12 +7,13 @@ defmodule Mix.Tasks.Pleroma.User do import Mix.Pleroma alias Ecto.Changeset alias Pleroma.User + alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.UserInviteToken alias Pleroma.Web.ActivityPub.Builder alias Pleroma.Web.ActivityPub.Pipeline @shortdoc "Manages Pleroma users" - @moduledoc File.read!("docs/administration/CLI_tasks/user.md") + @moduledoc File.read!("docs/docs/administration/CLI_tasks/user.md") def run(["new", nickname, email | rest]) do {options, [], []} = @@ -51,16 +52,14 @@ defmodule Mix.Tasks.Pleroma.User do 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) - } + - 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")} - admin: #{if(admin?, do: "true", else: "false")} """) - proceed? = assume_yes? or shell_yes?("Continue?") + proceed? = assume_yes? or shell_prompt("Continue?", "n") in ~w(Yn Y y) if proceed? do start_pleroma() @@ -74,7 +73,7 @@ defmodule Mix.Tasks.Pleroma.User do bio: bio } - changeset = User.register_changeset(%User{}, params, need_confirmation: false) + changeset = User.register_changeset(%User{}, params, is_confirmed: true) {:ok, _user} = User.register(changeset) shell_info("User #{nickname} created") @@ -107,21 +106,6 @@ defmodule Mix.Tasks.Pleroma.User do end end - def run(["toggle_activated", nickname]) do - start_pleroma() - - with %User{} = user <- User.get_cached_by_nickname(nickname) do - {:ok, user} = User.deactivate(user, !user.deactivated) - - shell_info( - "Activation status of #{nickname}: #{if(user.deactivated, do: "de", else: "")}activated" - ) - else - _ -> - shell_error("No user #{nickname}") - end - end - def run(["reset_password", nickname]) do start_pleroma() @@ -130,13 +114,9 @@ defmodule Mix.Tasks.Pleroma.User do shell_info("Generated password reset token for #{user.nickname}") IO.puts( - "URL: #{ - Pleroma.Web.Router.Helpers.reset_password_url( - Pleroma.Web.Endpoint, - :reset, - token.token - ) - }" + "URL: #{Pleroma.Web.Router.Helpers.reset_password_url(Pleroma.Web.Endpoint, + :reset, + token.token)}" ) else _ -> @@ -156,20 +136,41 @@ defmodule Mix.Tasks.Pleroma.User do end end + def run(["activate", nickname]) do + start_pleroma() + + with %User{} = user <- User.get_cached_by_nickname(nickname), + false <- user.is_active do + User.set_activation(user, true) + :timer.sleep(500) + + shell_info("Successfully activated #{nickname}") + else + true -> + shell_info("User #{nickname} already activated") + + _ -> + shell_error("No user #{nickname}") + end + end + def run(["deactivate", nickname]) do start_pleroma() - with %User{} = user <- User.get_cached_by_nickname(nickname) do - shell_info("Deactivating #{user.nickname}") - User.deactivate(user) + with %User{} = user <- User.get_cached_by_nickname(nickname), + true <- user.is_active do + User.set_activation(user, false) :timer.sleep(500) user = User.get_cached_by_id(user.id) if Enum.empty?(Enum.filter(User.get_friends(user), & &1.local)) do - shell_info("Successfully unsubscribed all local followers from #{user.nickname}") + shell_info("Successfully deactivated #{nickname} and unsubscribed all local followers") end else + false -> + shell_info("User #{nickname} already deactivated") + _ -> shell_error("No user #{nickname}") end @@ -179,7 +180,7 @@ defmodule Mix.Tasks.Pleroma.User do start_pleroma() Pleroma.User.Query.build(%{nickname: "@#{instance}"}) - |> Pleroma.RepoStreamer.chunk_stream(500) + |> Pleroma.Repo.chunk_stream(500, :batches) |> Stream.each(fn users -> users |> Enum.each(fn user -> @@ -196,17 +197,24 @@ defmodule Mix.Tasks.Pleroma.User do OptionParser.parse( rest, strict: [ - moderator: :boolean, admin: :boolean, - locked: :boolean + confirmed: :boolean, + locked: :boolean, + moderator: :boolean ] ) with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do user = - case Keyword.get(options, :moderator) do + case Keyword.get(options, :admin) do nil -> user - value -> set_moderator(user, value) + value -> set_admin(user, value) + end + + user = + case Keyword.get(options, :confirmed) do + nil -> user + value -> set_confirmation(user, value) end user = @@ -216,9 +224,9 @@ defmodule Mix.Tasks.Pleroma.User do end _user = - case Keyword.get(options, :admin) do + case Keyword.get(options, :moderator) do nil -> user - value -> set_admin(user, value) + value -> set_moderator(user, value) end else _ -> @@ -252,6 +260,25 @@ defmodule Mix.Tasks.Pleroma.User do end end + def run(["refetch_public_keys"]) do + start_pleroma() + + Pleroma.User.Query.build(%{ + external: true, + is_active: true + }) + |> refetch_public_keys() + end + + def run(["refetch_public_keys" | rest]) do + start_pleroma() + + Pleroma.User.Query.build(%{ + ap_id: rest + }) + |> refetch_public_keys() + end + def run(["invite" | rest]) do {options, [], []} = OptionParser.parse(rest, @@ -308,9 +335,7 @@ defmodule Mix.Tasks.Pleroma.User do end shell_info( - "ID: #{invite.id} | Token: #{invite.token} | Token type: #{invite.invite_type} | Used: #{ - invite.used - }#{expire_info}#{using_info}" + "ID: #{invite.id} | Token: #{invite.token} | Token type: #{invite.invite_type} | Used: #{invite.used}#{expire_info}#{using_info}" ) end) end @@ -338,13 +363,46 @@ defmodule Mix.Tasks.Pleroma.User do end end - def run(["toggle_confirmed", nickname]) do + def run(["change_email", nickname, email]) do + start_pleroma() + + with %User{} = user <- User.get_cached_by_nickname(nickname) do + user + |> User.update_changeset(%{"email" => email}) + |> User.update_and_set_cache() + + shell_info("#{nickname}'s email updated") + end + end + + def run(["show", nickname]) do + start_pleroma() + + nickname + |> User.get_cached_by_nickname() + |> IO.inspect() + end + + def run(["send_confirmation", nickname]) do + start_pleroma() + + with %User{} = user <- User.get_cached_by_nickname(nickname) do + user + |> Pleroma.Emails.UserEmail.account_confirmation_email() + |> IO.inspect() + |> Pleroma.Emails.Mailer.deliver!() + + shell_info("#{nickname}'s email sent") + end + end + + def run(["confirm", nickname]) do start_pleroma() with %User{} = user <- User.get_cached_by_nickname(nickname) do - {:ok, user} = User.toggle_confirmation(user) + {:ok, user} = User.confirm(user) - message = if user.confirmation_pending, do: "needs", else: "doesn't need" + message = if !user.is_confirmed, do: "needs", else: "doesn't need" shell_info("#{nickname} #{message} confirmation.") else @@ -353,6 +411,42 @@ defmodule Mix.Tasks.Pleroma.User do end end + def run(["confirm_all"]) do + start_pleroma() + + Pleroma.User.Query.build(%{ + local: true, + is_active: true, + is_moderator: false, + is_admin: false, + invisible: false + }) + |> Pleroma.Repo.chunk_stream(500, :batches) + |> Stream.each(fn users -> + users + |> Enum.each(fn user -> User.set_confirmation(user, true) end) + end) + |> Stream.run() + end + + def run(["unconfirm_all"]) do + start_pleroma() + + Pleroma.User.Query.build(%{ + local: true, + is_active: true, + is_moderator: false, + is_admin: false, + invisible: false + }) + |> Pleroma.Repo.chunk_stream(500, :batches) + |> Stream.each(fn users -> + users + |> Enum.each(fn user -> User.set_confirmation(user, false) end) + end) + |> Stream.run() + end + def run(["sign_out", nickname]) do start_pleroma() @@ -366,24 +460,119 @@ defmodule Mix.Tasks.Pleroma.User do end end + def run(["blocking", nickname]) do + start_pleroma() + + with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do + blocks = User.following_ap_ids(user) + IO.inspect(blocks, limit: :infinity) + end + end + + def run(["timeline_query", nickname]) do + start_pleroma() + + params = %{local: true} + + with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do + followed_hashtags = + user + |> User.followed_hashtags() + |> Enum.map(& &1.id) + + params = + params + |> Map.put(:type, ["Create", "Announce"]) + |> Map.put(:limit, 20) + |> Map.put(:blocking_user, user) + |> Map.put(:muting_user, user) + |> Map.put(:reply_filtering_user, user) + |> Map.put(:announce_filtering_user, user) + |> Map.put(:user, user) + |> Map.put(:local_only, params[:local]) + |> Map.put(:hashtags, followed_hashtags) + |> Map.delete(:local) + + _activities = + [user.ap_id | User.following(user)] + |> ActivityPub.fetch_activities(params) + end + end + def run(["list"]) do start_pleroma() Pleroma.User.Query.build(%{local: true}) - |> Pleroma.RepoStreamer.chunk_stream(500) + |> Pleroma.Repo.chunk_stream(500, :batches) |> Stream.each(fn users -> users |> Enum.each(fn user -> shell_info( - "#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{ - user.locked - }, deactivated: #{user.deactivated}" + "#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{user.is_locked}, is_active: #{user.is_active}" ) end) end) |> Stream.run() end + def run(["fix_follow_state", local_user, remote_user]) do + start_pleroma() + + with {:local, %User{} = local} <- {:local, User.get_by_nickname(local_user)}, + {:remote, %User{} = remote} <- {:remote, User.get_by_nickname(remote_user)}, + {:follow_data, %{data: %{"state" => request_state}}} <- + {:follow_data, Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(local, remote)} do + calculated_state = User.following?(local, remote) + + IO.puts( + "Request state is #{request_state}, vs calculated state of following=#{calculated_state}" + ) + + if calculated_state == false && request_state == "accept" do + IO.puts("Discrepancy found, fixing") + Pleroma.Web.CommonAPI.reject_follow_request(local, remote) + shell_info("Relationship fixed") + else + shell_info("No discrepancy found") + end + else + {:local, _} -> + shell_error("No local user #{local_user}") + + {:remote, _} -> + shell_error("No remote user #{remote_user}") + + {:follow_data, _} -> + shell_error("No follow data for #{local_user} and #{remote_user}") + end + end + + def run(["convert_id", id]) do + {:ok, uuid} = FlakeId.Ecto.Type.dump(id) + {:ok, raw_id} = Ecto.UUID.load(uuid) + shell_info(raw_id) + end + + defp refetch_public_keys(query) do + query + |> Pleroma.Repo.chunk_stream(50, :batches) + |> Stream.each(fn users -> + users + |> Enum.each(fn user -> + IO.puts("Re-Resolving: #{user.ap_id}") + + with {:ok, user} <- Pleroma.User.fetch_by_ap_id(user.ap_id), + changeset <- Pleroma.User.update_changeset(user), + {:ok, _user} <- Pleroma.User.update_and_set_cache(changeset) do + :ok + else + error -> IO.puts("Could not resolve: #{user.ap_id}, #{inspect(error)}") + end + end) + end) + |> Stream.run() + end + defp set_moderator(user, value) do {:ok, user} = user @@ -404,10 +593,17 @@ defmodule Mix.Tasks.Pleroma.User do defp set_locked(user, value) do {:ok, user} = user - |> Changeset.change(%{locked: value}) + |> Changeset.change(%{is_locked: value}) |> User.update_and_set_cache() - shell_info("Locked status of #{user.nickname}: #{user.locked}") + shell_info("Locked status of #{user.nickname}: #{user.is_locked}") + user + end + + defp set_confirmation(user, value) do + {:ok, user} = User.set_confirmation(user, value) + + shell_info("Confirmation status of #{user.nickname}: #{user.is_confirmed}") user end end