From 4b7c11e3f928befaa13daf142a2405284b0d07e5 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Mon, 4 Nov 2019 20:44:24 +0300 Subject: excluded invisible actors from gets /api/v1/accounts/:id --- lib/pleroma/user.ex | 31 ++++++++++++---------- lib/pleroma/web/activity_pub/relay.ex | 1 - .../mastodon_api/controllers/account_controller.ex | 2 +- 3 files changed, 18 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f8c2db1e1..abd1dd936 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -131,6 +131,8 @@ defmodule Pleroma.User do def visible_for?(user, for_user \\ nil) + def visible_for?(%User{invisible: true}, _), do: false + def visible_for?(%User{id: user_id}, %User{id: for_id}) when user_id == for_id, do: true def visible_for?(%User{} = user, for_user) do @@ -1314,22 +1316,23 @@ defmodule Pleroma.User do end end - @doc "Creates an internal service actor by URI if missing. Optionally takes nickname for addressing." + @doc """ + Creates an internal service actor by URI if missing. + Optionally takes nickname for addressing. + """ def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do - with %User{} = user <- get_cached_by_ap_id(uri) do - user - else - _ -> - {:ok, user} = - %User{} - |> cast(%{}, [:ap_id, :nickname, :local]) - |> put_change(:ap_id, uri) - |> put_change(:nickname, nickname) - |> put_change(:local, true) - |> put_change(:follower_address, uri <> "/followers") - |> Repo.insert() + with user when is_nil(user) <- get_cached_by_ap_id(uri) do + {:ok, user} = + %User{ + invisible: true, + local: true, + ap_id: uri, + nickname: nickname, + follower_address: uri <> "/followers" + } + |> Repo.insert() - user + user end end diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex index fc2619680..99a804568 100644 --- a/lib/pleroma/web/activity_pub/relay.ex +++ b/lib/pleroma/web/activity_pub/relay.ex @@ -14,7 +14,6 @@ defmodule Pleroma.Web.ActivityPub.Relay do relay_ap_id() |> User.get_or_create_service_actor_by_ap_id() - {:ok, actor} = User.set_invisible(actor, true) actor end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 73fad519e..8f5b91f04 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -238,7 +238,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do @doc "GET /api/v1/accounts/:id" def show(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user), - true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do + true <- User.visible_for?(user, for_user) do render(conn, "show.json", user: user, for: for_user) else _e -> render_error(conn, :not_found, "Can't find user") -- cgit v1.2.3 From 62bc0657e7ad78a708c1bb6a82eb98aa1f01e819 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Tue, 5 Nov 2019 08:55:41 +0300 Subject: excluded invisible users from search results --- lib/pleroma/user/search.ex | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex index 09664db76..b1bb9d4da 100644 --- a/lib/pleroma/user/search.ex +++ b/lib/pleroma/user/search.ex @@ -45,6 +45,7 @@ defmodule Pleroma.User.Search do for_user |> base_query(following) |> filter_blocked_user(for_user) + |> filter_invisible_users() |> filter_blocked_domains(for_user) |> fts_search(query_string) |> trigram_rank(query_string) @@ -98,6 +99,10 @@ defmodule Pleroma.User.Search do defp base_query(_user, false), do: User defp base_query(user, true), do: User.get_followers_query(user) + defp filter_invisible_users(query) do + from(q in query, where: q.invisible == false) + end + defp filter_blocked_user(query, %User{blocks: blocks}) when length(blocks) > 0 do from(q in query, where: not (q.ap_id in ^blocks)) -- cgit v1.2.3 From e52955c961a225618f00f8f0fc0e7dcbf5a51e23 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Tue, 5 Nov 2019 10:50:03 +0300 Subject: update following_relationship.ex --- lib/pleroma/following_relationship.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex index 2ffac17ee..3aff9fb76 100644 --- a/lib/pleroma/following_relationship.ex +++ b/lib/pleroma/following_relationship.ex @@ -101,7 +101,7 @@ defmodule Pleroma.FollowingRelationship do |> select([r, u], u.follower_address) |> Repo.all() - if not user.local or user.nickname in [nil, "internal.fetch"] do + if not user.local or user.invisible do following else [user.follower_address | following] -- cgit v1.2.3 From 46eb160135cf408fee87bb76fc46acfc51af901d Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Tue, 19 Nov 2019 20:14:02 +0900 Subject: AdminAPI: Confirm user account, resend confirmation email --- lib/pleroma/moderation_log.ex | 26 +++++++++++++- lib/pleroma/user.ex | 9 +++++ lib/pleroma/web/admin_api/admin_api_controller.ex | 41 +++++++++++++++++++---- lib/pleroma/web/admin_api/views/account_view.ex | 3 +- lib/pleroma/web/router.ex | 3 ++ 5 files changed, 74 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/moderation_log.ex b/lib/pleroma/moderation_log.ex index ffa5dc25d..706f089dc 100644 --- a/lib/pleroma/moderation_log.ex +++ b/lib/pleroma/moderation_log.ex @@ -624,7 +624,31 @@ defmodule Pleroma.ModerationLog do "subject" => subjects } }) do - "@#{actor_nickname} force password reset for users: #{users_to_nicknames_string(subjects)}" + "@#{actor_nickname} forced password reset for users: #{users_to_nicknames_string(subjects)}" + end + + @spec get_log_entry_message(ModerationLog) :: String.t() + def get_log_entry_message(%ModerationLog{ + data: %{ + "actor" => %{"nickname" => actor_nickname}, + "action" => "confirm_email", + "subject" => subjects + } + }) do + "@#{actor_nickname} confirmed email for users: #{users_to_nicknames_string(subjects)}" + end + + @spec get_log_entry_message(ModerationLog) :: String.t() + def get_log_entry_message(%ModerationLog{ + data: %{ + "actor" => %{"nickname" => actor_nickname}, + "action" => "resend_confirmation_email", + "subject" => subjects + } + }) do + "@#{actor_nickname} re-sent confirmation email for users: #{ + users_to_nicknames_string(subjects) + }" end defp nicknames_to_string(nicknames) do diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f8c2db1e1..f031d2179 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -489,6 +489,10 @@ defmodule Pleroma.User do end end + def try_send_confirmation_email(users) do + Enum.map(users, &try_send_confirmation_email/1) + end + def needs_update?(%User{local: true}), do: false def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true @@ -1572,6 +1576,11 @@ defmodule Pleroma.User do |> update_and_set_cache() end + @spec toggle_confirmation([User.t()]) :: [{:ok, User.t()} | {:error, Changeset.t()}] + def toggle_confirmation(users) do + Enum.map(users, &toggle_confirmation/1) + end + def get_mascot(%{mascot: %{} = mascot}) when not is_nil(mascot) do mascot end diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 8c1318d1b..c46ce76da 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -335,7 +335,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do } with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)), - {:ok, users, count} <- filter_relay_user(users, count), + {:ok, users, count} <- filter_service_users(users, count), do: conn |> json( @@ -347,15 +347,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do ) end - defp filter_relay_user(users, count) do - filtered_users = Enum.reject(users, &relay_user?/1) - count = if Enum.any?(users, &relay_user?/1), do: length(filtered_users), else: count + defp filter_service_users(users, count) do + filtered_users = Enum.reject(users, &service_user?/1) + count = if Enum.any?(users, &service_user?/1), do: length(filtered_users), else: count {:ok, filtered_users, count} end - defp relay_user?(user) do - user.ap_id == Relay.relay_ap_id() + defp service_user?(user) do + String.match?(user.ap_id, ~r/.*\/relay$/) or + String.match?(user.ap_id, ~r/.*\/internal\/fetch$/) end @filters ~w(local external active deactivated is_admin is_moderator) @@ -799,6 +800,34 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do conn |> json("ok") end + def confirm_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do + users = nicknames |> Enum.map(&User.get_cached_by_nickname/1) + + User.toggle_confirmation(users) + + ModerationLog.insert_log(%{ + actor: admin, + subject: users, + action: "confirm_email" + }) + + conn |> json("") + end + + def resend_confirmation_email(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do + users = nicknames |> Enum.map(&User.get_cached_by_nickname/1) + + User.try_send_confirmation_email(users) + + ModerationLog.insert_log(%{ + actor: admin, + subject: users, + action: "resend_confirmation_email" + }) + + conn |> json("") + end + def errors(conn, {:error, :not_found}) do conn |> put_status(:not_found) diff --git a/lib/pleroma/web/admin_api/views/account_view.ex b/lib/pleroma/web/admin_api/views/account_view.ex index 6aa7257ce..d9dba5c51 100644 --- a/lib/pleroma/web/admin_api/views/account_view.ex +++ b/lib/pleroma/web/admin_api/views/account_view.ex @@ -36,7 +36,8 @@ defmodule Pleroma.Web.AdminAPI.AccountView do "deactivated" => user.deactivated, "local" => user.local, "roles" => User.roles(user), - "tags" => user.tags || [] + "tags" => user.tags || [], + "confirmation_pending" => user.confirmation_pending } end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 9b8b373b8..b654d00c7 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -177,6 +177,9 @@ defmodule Pleroma.Web.Router do get("/users/:nickname", AdminAPIController, :user_show) get("/users/:nickname/statuses", AdminAPIController, :list_user_statuses) + patch("/users/confirm_email", AdminAPIController, :confirm_email) + patch("/users/resend_confirmation_email", AdminAPIController, :resend_confirmation_email) + get("/reports", AdminAPIController, :list_reports) get("/grouped_reports", AdminAPIController, :list_grouped_reports) get("/reports/:id", AdminAPIController, :report_show) -- cgit v1.2.3 From ff9133b978edb637081882e7efd49e2f538e9e15 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Tue, 19 Nov 2019 16:01:17 -0600 Subject: Allow mix tasks to always run with debug logging --- lib/mix/pleroma.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/mix/pleroma.ex b/lib/mix/pleroma.ex index faeb30e1d..94eeb7d68 100644 --- a/lib/mix/pleroma.ex +++ b/lib/mix/pleroma.ex @@ -6,6 +6,7 @@ defmodule Mix.Pleroma do @doc "Common functions to be reused in mix tasks" def start_pleroma do Application.put_env(:phoenix, :serve_endpoints, false, persistent: true) + Application.put_env(:logger, :console, level: :debug) {:ok, _} = Application.ensure_all_started(:pleroma) end -- cgit v1.2.3 From edaae845afc63d558c22019b3b3f87bc510a3bdf Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Wed, 20 Nov 2019 11:55:30 -0600 Subject: Some tasks try to set log level in test environment, but we were stripping logs belog :warn. Ensure console backend logs in test environment are :warn, but mix tasks run in test env do not run with :debug because it's far too verbose. --- lib/mix/pleroma.ex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/mix/pleroma.ex b/lib/mix/pleroma.ex index 94eeb7d68..73a076a53 100644 --- a/lib/mix/pleroma.ex +++ b/lib/mix/pleroma.ex @@ -6,7 +6,11 @@ defmodule Mix.Pleroma do @doc "Common functions to be reused in mix tasks" def start_pleroma do Application.put_env(:phoenix, :serve_endpoints, false, persistent: true) - Application.put_env(:logger, :console, level: :debug) + + if Pleroma.Config.get(:env) != :test do + Application.put_env(:logger, :console, level: :debug) + end + {:ok, _} = Application.ensure_all_started(:pleroma) end -- cgit v1.2.3 From d38ab4bb89299f643d8529d46e02521a525b84e6 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Thu, 21 Nov 2019 16:31:13 +0700 Subject: Fix user.following_count --- lib/pleroma/user.ex | 56 ++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index fcb1d5143..34370be20 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -67,8 +67,7 @@ defmodule Pleroma.User do field(:source_data, :map, default: %{}) field(:note_count, :integer, default: 0) field(:follower_count, :integer, default: 0) - # Should be filled in only for remote users - field(:following_count, :integer, default: nil) + field(:following_count, :integer, default: 0) field(:locked, :boolean, default: false) field(:confirmation_pending, :boolean, default: false) field(:password_reset_pending, :boolean, default: false) @@ -177,19 +176,17 @@ defmodule Pleroma.User do def ap_following(%User{} = user), do: "#{ap_id(user)}/following" def user_info(%User{} = user, args \\ %{}) do - following_count = - Map.get(args, :following_count, user.following_count || following_count(user)) - + following_count = Map.get(args, :following_count, user.following_count) follower_count = Map.get(args, :follower_count, user.follower_count) %{ note_count: user.note_count, locked: user.locked, confirmation_pending: user.confirmation_pending, - default_scope: user.default_scope + default_scope: user.default_scope, + follower_count: follower_count, + following_count: following_count } - |> Map.put(:following_count, following_count) - |> Map.put(:follower_count, follower_count) end def follow_state(%User{} = user, %User{} = target) do @@ -522,14 +519,9 @@ defmodule Pleroma.User do @doc "A mass follow for local users. Respects blocks in both directions but does not create activities." @spec follow_all(User.t(), list(User.t())) :: {atom(), User.t()} def follow_all(follower, followeds) do - followeds = - Enum.reject(followeds, fn followed -> - blocks?(follower, followed) || blocks?(followed, follower) - end) - - Enum.each(followeds, &follow(follower, &1, "accept")) - - Enum.each(followeds, &update_follower_count/1) + followeds + |> Enum.reject(fn followed -> blocks?(follower, followed) || blocks?(followed, follower) end) + |> Enum.each(&follow(follower, &1, "accept")) set_cache(follower) end @@ -549,11 +541,11 @@ defmodule Pleroma.User do true -> FollowingRelationship.follow(follower, followed, state) - follower = maybe_update_following_count(follower) - {:ok, _} = update_follower_count(followed) - set_cache(follower) + follower + |> update_following_count() + |> set_cache() end end @@ -561,11 +553,12 @@ defmodule Pleroma.User do if following?(follower, followed) and follower.ap_id != followed.ap_id do FollowingRelationship.unfollow(follower, followed) - follower = maybe_update_following_count(follower) - {:ok, followed} = update_follower_count(followed) - set_cache(follower) + {:ok, follower} = + follower + |> update_following_count() + |> set_cache() {:ok, follower, Utils.fetch_latest_follow(follower, followed)} else @@ -895,8 +888,8 @@ defmodule Pleroma.User do end end - @spec maybe_update_following_count(User.t()) :: User.t() - def maybe_update_following_count(%User{local: false} = user) do + @spec update_following_count(User.t()) :: User.t() + def update_following_count(%User{local: false} = user) do if Pleroma.Config.get([:instance, :external_user_synchronization]) do maybe_fetch_follow_information(user) else @@ -904,7 +897,13 @@ defmodule Pleroma.User do end end - def maybe_update_following_count(user), do: user + def update_following_count(%User{local: true} = user) do + following_count = FollowingRelationship.following_count(user) + + user + |> follow_information_changeset(%{following_count: following_count}) + |> Repo.update!() + end def set_unread_conversation_count(%User{local: true} = user) do unread_query = Participation.unread_conversation_count_for_user(user) @@ -1097,7 +1096,12 @@ defmodule Pleroma.User do def deactivate(%User{} = user, status) do with {:ok, user} <- set_activation_status(user, status) do - Enum.each(get_followers(user), &invalidate_cache/1) + user + |> get_followers() + |> Enum.filter(& &1.local) + |> Enum.each(fn follower -> + follower |> update_following_count() |> set_cache() + end) # Only update local user counts, remote will be update during the next pull. user -- cgit v1.2.3 From 320690f7a5bf1622e25114b6ad4c0b0c5a252748 Mon Sep 17 00:00:00 2001 From: lain Date: Thu, 21 Nov 2019 14:03:01 +0100 Subject: Object: Use inspect to log missing preload. --- lib/pleroma/object.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index d9b41d710..cde0eddd9 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -63,7 +63,7 @@ defmodule Pleroma.Object do end defp warn_on_no_object_preloaded(ap_id) do - "Object.normalize() called without preloaded object (#{ap_id}). Consider preloading the object" + "Object.normalize() called without preloaded object (#{inspect(ap_id)}). Consider preloading the object" |> Logger.debug() Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}") -- cgit v1.2.3 From fbc379d68990b166e1034cfff252f975f793eba1 Mon Sep 17 00:00:00 2001 From: Alex Schroeder Date: Sun, 17 Nov 2019 21:58:30 +0100 Subject: Add CLI list users command --- lib/mix/tasks/pleroma/user.ex | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib') diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index 4e3b80db3..bc8eacda8 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -364,6 +364,24 @@ defmodule Mix.Tasks.Pleroma.User do end end + def run(["list"]) do + start_pleroma() + + Pleroma.User.Query.build(%{local: true}) + |> Pleroma.RepoStreamer.chunk_stream(500) + |> Stream.each(fn users -> + 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}" + ) + end) + end) + |> Stream.run() + end + defp set_moderator(user, value) do {:ok, user} = user -- cgit v1.2.3 From b64c7b35d429546695550b37ca1e690b46c86f5d Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Fri, 22 Nov 2019 09:11:36 +0900 Subject: Swap map with each --- lib/pleroma/user.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f031d2179..f1830509c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -490,7 +490,7 @@ defmodule Pleroma.User do end def try_send_confirmation_email(users) do - Enum.map(users, &try_send_confirmation_email/1) + Enum.each(users, &try_send_confirmation_email/1) end def needs_update?(%User{local: true}), do: false -- cgit v1.2.3