From e6aeb1d4a5c0e0e0e5e1e744b4062f7392ed0722 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 27 Dec 2018 15:46:18 +0300 Subject: [PATCH 1/3] [#471] Prevented rendering of inactive local accounts. --- lib/pleroma/user.ex | 2 ++ .../web/mastodon_api/views/account_view.ex | 22 ++++++++++++- .../web/twitter_api/views/user_view.ex | 33 +++++++++++++++---- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1f930479d..b8a7a3fae 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -47,6 +47,8 @@ def auth_active?(%User{} = user) do !Pleroma.Config.get([:instance, :account_activation_required]) end + def remote_or_auth_active?(%User{} = user), do: !user.local || auth_active?(user) + def superuser?(%User{} = user), do: user.info && User.Info.superuser?(user.info) def avatar_url(user) do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index aaaae2035..ba72e3a10 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -11,10 +11,30 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do alias Pleroma.HTML def render("accounts.json", %{users: users} = opts) do - render_many(users, AccountView, "account.json", opts) + users + |> render_many(AccountView, "account.json", opts) + |> Enum.filter(&Enum.any?/1) end def render("account.json", %{user: user} = opts) do + for_user = opts[:for] + + allow_render = + User.remote_or_auth_active?(user) || + (for_user && (for_user.id == user.id || User.superuser?(for_user))) + + if allow_render do + render("valid_account.json", opts) + else + render("invalid_account.json", opts) + end + end + + def render("invalid_account.json", _opts) do + %{} + end + + def render("valid_account.json", %{user: user} = opts) do image = User.avatar_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 6e489624f..41825f8f6 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -15,18 +15,39 @@ def render("show.json", %{user: user = %User{}} = assigns) do end def render("index.json", %{users: users, for: user}) do - render_many(users, Pleroma.Web.TwitterAPI.UserView, "user.json", for: user) + users + |> render_many(Pleroma.Web.TwitterAPI.UserView, "user.json", for: user) + |> Enum.filter(&Enum.any?/1) end def render("user.json", %{user: user = %User{}} = assigns) do + for_user = assigns[:for] + + allow_render = + User.remote_or_auth_active?(user) || + (for_user && (for_user.id == user.id || User.superuser?(for_user))) + + if allow_render do + render("valid_user.json", assigns) + else + render("invalid_user.json", assigns) + end + end + + def render("invalid_user.json", _assigns) do + %{} + end + + def render("valid_user.json", %{user: user = %User{}} = assigns) do + for_user = assigns[:for] image = User.avatar_url(user) |> MediaProxy.url() {following, follows_you, statusnet_blocking} = - if assigns[:for] do + if for_user do { - User.following?(assigns[:for], user), - User.following?(user, assigns[:for]), - User.blocks?(assigns[:for], user) + User.following?(for_user, user), + User.following?(user, for_user), + User.blocks?(for_user, user) } else {false, false, false} @@ -51,7 +72,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do data = %{ "created_at" => user.inserted_at |> Utils.format_naive_asctime(), "description" => HTML.strip_tags((user.bio || "") |> String.replace("
", "\n")), - "description_html" => HTML.filter_tags(user.bio, User.html_filter_policy(assigns[:for])), + "description_html" => HTML.filter_tags(user.bio, User.html_filter_policy(for_user)), "favourites_count" => 0, "followers_count" => user_info[:follower_count], "following" => following, From 0d1788ce44cf7bf50aa40e56988be0d2e315d2e1 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 28 Dec 2018 14:35:25 +0300 Subject: [PATCH 2/3] [#471] Factored out User.visible_for?/2. --- lib/pleroma/user.ex | 6 ++++++ lib/pleroma/web/mastodon_api/views/account_view.ex | 14 +++----------- lib/pleroma/web/twitter_api/views/user_view.ex | 14 +++----------- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b8a7a3fae..7d97bf7e5 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -49,6 +49,12 @@ def auth_active?(%User{} = user) do def remote_or_auth_active?(%User{} = user), do: !user.local || auth_active?(user) + def visible_for?(%User{} = user, for_user \\ nil) do + User.remote_or_auth_active?(user) || (for_user && for_user.id == user.id) || + User.superuser?(for_user) + end + + def superuser?(nil), do: false def superuser?(%User{} = user), do: user.info && User.Info.superuser?(user.info) def avatar_url(user) do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index ba72e3a10..32cb1ac60 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -17,17 +17,9 @@ def render("accounts.json", %{users: users} = opts) do end def render("account.json", %{user: user} = opts) do - for_user = opts[:for] - - allow_render = - User.remote_or_auth_active?(user) || - (for_user && (for_user.id == user.id || User.superuser?(for_user))) - - if allow_render do - render("valid_account.json", opts) - else - render("invalid_account.json", opts) - end + if User.visible_for?(user, opts[:for]), + do: render("valid_account.json", opts), + else: render("invalid_account.json", opts) end def render("invalid_account.json", _opts) do diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 41825f8f6..890d4234e 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -21,17 +21,9 @@ def render("index.json", %{users: users, for: user}) do end def render("user.json", %{user: user = %User{}} = assigns) do - for_user = assigns[:for] - - allow_render = - User.remote_or_auth_active?(user) || - (for_user && (for_user.id == user.id || User.superuser?(for_user))) - - if allow_render do - render("valid_user.json", assigns) - else - render("invalid_user.json", assigns) - end + if User.visible_for?(user, assigns[:for]), + do: render("valid_user.json", assigns), + else: render("invalid_user.json", assigns) end def render("invalid_user.json", _assigns) do From 0a41786624454d26fd966748735a8f2333bf4012 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 28 Dec 2018 22:47:42 +0300 Subject: [PATCH 3/3] [#467] Refactored valid / invalid user rendering. --- .../web/mastodon_api/views/account_view.ex | 80 +++++++++---------- .../web/twitter_api/views/user_view.ex | 40 +++++----- 2 files changed, 56 insertions(+), 64 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 32cb1ac60..555383503 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -18,15 +18,48 @@ def render("accounts.json", %{users: users} = opts) do def render("account.json", %{user: user} = opts) do if User.visible_for?(user, opts[:for]), - do: render("valid_account.json", opts), - else: render("invalid_account.json", opts) + do: do_render("account.json", opts), + else: %{} end - def render("invalid_account.json", _opts) do - %{} + def render("mention.json", %{user: user}) do + %{ + id: to_string(user.id), + acct: user.nickname, + username: username_from_nickname(user.nickname), + url: user.ap_id + } end - def render("valid_account.json", %{user: user} = opts) do + def render("relationship.json", %{user: user, target: target}) do + follow_activity = Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, target) + + requested = + if follow_activity do + follow_activity.data["state"] == "pending" + else + false + end + + %{ + id: to_string(target.id), + following: User.following?(user, target), + followed_by: User.following?(target, user), + blocking: User.blocks?(user, target), + muting: false, + muting_notifications: false, + requested: requested, + domain_blocking: false, + showing_reblogs: false, + endorsed: false + } + end + + def render("relationships.json", %{user: user, targets: targets}) do + render_many(targets, AccountView, "relationship.json", user: user, as: :target) + end + + defp do_render("account.json", %{user: user} = opts) do image = User.avatar_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) @@ -84,43 +117,6 @@ def render("valid_account.json", %{user: user} = opts) do } end - def render("mention.json", %{user: user}) do - %{ - id: to_string(user.id), - acct: user.nickname, - username: username_from_nickname(user.nickname), - url: user.ap_id - } - end - - def render("relationship.json", %{user: user, target: target}) do - follow_activity = Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, target) - - requested = - if follow_activity do - follow_activity.data["state"] == "pending" - else - false - end - - %{ - id: to_string(target.id), - following: User.following?(user, target), - followed_by: User.following?(target, user), - blocking: User.blocks?(user, target), - muting: false, - muting_notifications: false, - requested: requested, - domain_blocking: false, - showing_reblogs: false, - endorsed: false - } - end - - def render("relationships.json", %{user: user, targets: targets}) do - render_many(targets, AccountView, "relationship.json", user: user, as: :target) - end - defp username_from_nickname(string) when is_binary(string) do hd(String.split(string, "@")) end diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 890d4234e..ede3c0d25 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -22,15 +22,28 @@ def render("index.json", %{users: users, for: user}) do def render("user.json", %{user: user = %User{}} = assigns) do if User.visible_for?(user, assigns[:for]), - do: render("valid_user.json", assigns), - else: render("invalid_user.json", assigns) + do: do_render("user.json", assigns), + else: %{} end - def render("invalid_user.json", _assigns) do - %{} + def render("short.json", %{ + user: %User{ + nickname: nickname, + id: id, + ap_id: ap_id, + name: name + } + }) do + %{ + "fullname" => name, + "id" => id, + "ostatus_uri" => ap_id, + "profile_url" => ap_id, + "screen_name" => nickname + } end - def render("valid_user.json", %{user: user = %User{}} = assigns) do + defp do_render("user.json", %{user: user = %User{}} = assigns) do for_user = assigns[:for] image = User.avatar_url(user) |> MediaProxy.url() @@ -110,23 +123,6 @@ def render("valid_user.json", %{user: user = %User{}} = assigns) do end end - def render("short.json", %{ - user: %User{ - nickname: nickname, - id: id, - ap_id: ap_id, - name: name - } - }) do - %{ - "fullname" => name, - "id" => id, - "ostatus_uri" => ap_id, - "profile_url" => ap_id, - "screen_name" => nickname - } - end - defp image_url(%{"url" => [%{"href" => href} | _]}), do: href defp image_url(_), do: nil