[#2456] Dropped support for embedded `pleroma/account/relationship` in statuses and notifications.

This commit is contained in:
Ivan Tashkinov 2020-05-09 18:05:44 +03:00
parent b2924ab1fb
commit 14a49a0483
14 changed files with 52 additions and 174 deletions

View File

@ -6,7 +6,9 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
use Pleroma.Web, :view use Pleroma.Web, :view
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
def render("index.json", %{users: users, count: count, page_size: page_size}) do def render("index.json", %{users: users, count: count, page_size: page_size}) do
@ -119,6 +121,13 @@ def render("create-error.json", %{changeset: %Ecto.Changeset{changes: changes, e
} }
end end
def merge_account_views(%User{} = user) do
MastodonAPI.AccountView.render("show.json", %{user: user, skip_relationships: true})
|> Map.merge(AdminAPI.AccountView.render("show.json", %{user: user}))
end
def merge_account_views(_), do: %{}
defp parse_error([]), do: "" defp parse_error([]), do: ""
defp parse_error(errors) do defp parse_error(errors) do

View File

@ -10,9 +10,10 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
alias Pleroma.Web.AdminAPI alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.Report alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
defdelegate merge_account_views(user), to: AdminAPI.AccountView
def render("index.json", %{reports: reports}) do def render("index.json", %{reports: reports}) do
%{ %{
reports: reports:
@ -71,11 +72,4 @@ def render("show_note.json", %{
created_at: Utils.to_masto_date(inserted_at) created_at: Utils.to_masto_date(inserted_at)
} }
end end
defp merge_account_views(%User{} = user) do
MastodonAPI.AccountView.render("show.json", %{user: user, skip_relationships: true})
|> Map.merge(AdminAPI.AccountView.render("show.json", %{user: user}))
end
defp merge_account_views(_), do: %{}
end end

View File

@ -7,26 +7,19 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
require Pleroma.Constants require Pleroma.Constants
alias Pleroma.User
alias Pleroma.Web.AdminAPI alias Pleroma.Web.AdminAPI
alias Pleroma.Web.MastodonAPI alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MastodonAPI.StatusView
defdelegate merge_account_views(user), to: AdminAPI.AccountView
def render("index.json", opts) do def render("index.json", opts) do
safe_render_many(opts.activities, __MODULE__, "show.json", opts) safe_render_many(opts.activities, __MODULE__, "show.json", opts)
end end
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
user = StatusView.get_user(activity.data["actor"]) user = MastodonAPI.StatusView.get_user(activity.data["actor"])
StatusView.render("show.json", opts) MastodonAPI.StatusView.render("show.json", opts)
|> Map.merge(%{account: merge_account_views(user)}) |> Map.merge(%{account: merge_account_views(user)})
end end
defp merge_account_views(%User{} = user) do
MastodonAPI.AccountView.render("show.json", %{user: user, skip_relationships: true})
|> Map.merge(AdminAPI.AccountView.render("show.json", %{user: user}))
end
defp merge_account_views(_), do: %{}
end end

View File

@ -103,9 +103,4 @@ def try_render(conn, _, _) do
def put_if_exist(map, _key, nil), do: map def put_if_exist(map, _key, nil), do: map
def put_if_exist(map, key, value), do: Map.put(map, key, value) def put_if_exist(map, key, value), do: Map.put(map, key, value)
@doc "Whether to skip `account.pleroma.relationship` rendering for statuses/notifications"
def skip_relationships?(params) do
not truthy_param?(params["with_relationships"])
end
end end

View File

@ -10,8 +10,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
add_link_headers: 2, add_link_headers: 2,
truthy_param?: 1, truthy_param?: 1,
assign_account_by_id: 2, assign_account_by_id: 2,
json_response: 3, json_response: 3
skip_relationships?: 1
] ]
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@ -247,8 +246,7 @@ def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: reading_user, for: reading_user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
else else
_e -> render_error(conn, :not_found, "Can't find user") _e -> render_error(conn, :not_found, "Can't find user")

View File

@ -5,7 +5,7 @@
defmodule Pleroma.Web.MastodonAPI.NotificationController do defmodule Pleroma.Web.MastodonAPI.NotificationController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1] import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.OAuthScopesPlug
@ -50,8 +50,7 @@ def index(%{assigns: %{user: user}} = conn, params) do
|> add_link_headers(notifications) |> add_link_headers(notifications)
|> render("index.json", |> render("index.json",
notifications: notifications, notifications: notifications,
for: user, for: user
skip_relationships: skip_relationships?(params)
) )
end end

View File

@ -5,8 +5,6 @@
defmodule Pleroma.Web.MastodonAPI.SearchController do defmodule Pleroma.Web.MastodonAPI.SearchController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [skip_relationships?: 1]
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Plugs.RateLimiter alias Pleroma.Plugs.RateLimiter
@ -71,7 +69,6 @@ defp do_search(version, %{assigns: %{user: user}} = conn, %{q: query} = params)
defp search_options(params, user) do defp search_options(params, user) do
[ [
skip_relationships: skip_relationships?(params),
resolve: params[:resolve], resolve: params[:resolve],
following: params[:following], following: params[:following],
limit: params[:limit], limit: params[:limit],
@ -100,8 +97,7 @@ defp resource_search(_, "statuses", query, options) do
StatusView.render("index.json", StatusView.render("index.json",
activities: statuses, activities: statuses,
for: options[:for_user], for: options[:for_user],
as: :activity, as: :activity
skip_relationships: options[:skip_relationships]
) )
end end

View File

@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, import Pleroma.Web.ControllerHelper,
only: [try_render: 3, add_link_headers: 2, skip_relationships?: 1] only: [try_render: 3, add_link_headers: 2]
require Ecto.Query require Ecto.Query
@ -102,7 +102,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
`ids` query param is required `ids` query param is required
""" """
def index(%{assigns: %{user: user}} = conn, %{"ids" => ids} = params) do def index(%{assigns: %{user: user}} = conn, %{"ids" => ids} = _params) do
limit = 100 limit = 100
activities = activities =
@ -114,8 +114,7 @@ def index(%{assigns: %{user: user}} = conn, %{"ids" => ids} = params) do
render(conn, "index.json", render(conn, "index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -370,8 +369,7 @@ def favourites(%{assigns: %{user: %User{} = user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -393,8 +391,7 @@ def bookmarks(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
end end

View File

@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, import Pleroma.Web.ControllerHelper,
only: [add_link_headers: 2, add_link_headers: 3, truthy_param?: 1, skip_relationships?: 1] only: [add_link_headers: 2, add_link_headers: 3, truthy_param?: 1]
alias Pleroma.Pagination alias Pleroma.Pagination
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@ -59,8 +59,7 @@ def home(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -83,8 +82,7 @@ def direct(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -118,8 +116,7 @@ def public(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
end end
@ -166,8 +163,7 @@ def hashtag(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -195,8 +191,7 @@ def list(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params) do
render(conn, "index.json", render(conn, "index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
else else
_e -> render_error(conn, :forbidden, "Error.") _e -> render_error(conn, :forbidden, "Error.")

View File

@ -15,8 +15,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
def render("index.json", %{notifications: notifications, for: reading_user} = opts) do def render("index.json", %{notifications: notifications, for: reading_user} = opts) do
opts = Map.merge(%{skip_relationships: true}, opts)
activities = Enum.map(notifications, & &1.activity) activities = Enum.map(notifications, & &1.activity)
parent_activities = parent_activities =
@ -53,9 +51,7 @@ def render("index.json", %{notifications: notifications, for: reading_user} = op
|> Enum.filter(& &1) |> Enum.filter(& &1)
|> Kernel.++(move_activities_targets) |> Kernel.++(move_activities_targets)
UserRelationship.view_relationships_option(reading_user, actors, UserRelationship.view_relationships_option(reading_user, actors, source_mutes_only: true)
source_mutes_only: opts[:skip_relationships]
)
end end
opts = opts =
@ -73,8 +69,6 @@ def render(
for: reading_user for: reading_user
} = opts } = opts
) do ) do
opts = Map.merge(%{skip_relationships: true}, opts)
actor = User.get_cached_by_ap_id(activity.data["actor"]) actor = User.get_cached_by_ap_id(activity.data["actor"])
parent_activity_fn = fn -> parent_activity_fn = fn ->
@ -87,15 +81,15 @@ def render(
mastodon_type = Activity.mastodon_notification_type(activity) mastodon_type = Activity.mastodon_notification_type(activity)
render_opts = %{ # Note: :relationships contain user mutes (needed for :muted flag in :status)
relationships: opts[:relationships], status_render_opts = %{relationships: opts[:relationships]}
skip_relationships: opts[:skip_relationships]
} account_render_opts = %{skip_relationships: true}
with %{id: _} = account <- with %{id: _} = account <-
AccountView.render( AccountView.render(
"show.json", "show.json",
Map.merge(render_opts, %{user: actor, for: reading_user}) Map.merge(account_render_opts, %{user: actor, for: reading_user})
) do ) do
response = %{ response = %{
id: to_string(notification.id), id: to_string(notification.id),
@ -109,21 +103,20 @@ def render(
case mastodon_type do case mastodon_type do
"mention" -> "mention" ->
put_status(response, activity, reading_user, render_opts) put_status(response, activity, reading_user, status_render_opts)
"favourite" -> "favourite" ->
put_status(response, parent_activity_fn.(), reading_user, render_opts) put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
"reblog" -> "reblog" ->
put_status(response, parent_activity_fn.(), reading_user, render_opts) put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
"move" -> "move" ->
# Note: :skip_relationships option being applied to _account_ rendering (here) put_target(response, activity, reading_user, account_render_opts)
put_target(response, activity, reading_user, render_opts)
"pleroma:emoji_reaction" -> "pleroma:emoji_reaction" ->
response response
|> put_status(parent_activity_fn.(), reading_user, render_opts) |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
|> put_emoji(activity) |> put_emoji(activity)
type when type in ["follow", "follow_request"] -> type when type in ["follow", "follow_request"] ->

View File

@ -76,8 +76,6 @@ defp reblogged?(activity, user) do
end end
def render("index.json", opts) do def render("index.json", opts) do
opts = Map.merge(%{skip_relationships: true}, opts)
reading_user = opts[:for] reading_user = opts[:for]
# To do: check AdminAPIControllerTest on the reasons behind nil activities in the list # To do: check AdminAPIControllerTest on the reasons behind nil activities in the list
@ -109,9 +107,7 @@ def render("index.json", opts) do
|> Enum.map(&get_user(&1.data["actor"], false)) |> Enum.map(&get_user(&1.data["actor"], false))
|> Enum.filter(& &1) |> Enum.filter(& &1)
UserRelationship.view_relationships_option(reading_user, actors, UserRelationship.view_relationships_option(reading_user, actors, source_mutes_only: true)
source_mutes_only: opts[:skip_relationships]
)
end end
opts = opts =
@ -127,8 +123,6 @@ def render(
"show.json", "show.json",
%{activity: %{data: %{"type" => "Announce", "object" => _object}} = activity} = opts %{activity: %{data: %{"type" => "Announce", "object" => _object}} = activity} = opts
) do ) do
opts = Map.merge(%{skip_relationships: true}, opts)
user = get_user(activity.data["actor"]) user = get_user(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"]) created_at = Utils.to_masto_date(activity.data["published"])
activity_object = Object.normalize(activity) activity_object = Object.normalize(activity)
@ -167,8 +161,7 @@ def render(
AccountView.render("show.json", %{ AccountView.render("show.json", %{
user: user, user: user,
for: opts[:for], for: opts[:for],
relationships: opts[:relationships], skip_relationships: true
skip_relationships: opts[:skip_relationships]
}), }),
in_reply_to_id: nil, in_reply_to_id: nil,
in_reply_to_account_id: nil, in_reply_to_account_id: nil,
@ -202,8 +195,6 @@ def render(
end end
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
opts = Map.merge(%{skip_relationships: true}, opts)
object = Object.normalize(activity) object = Object.normalize(activity)
user = get_user(activity.data["actor"]) user = get_user(activity.data["actor"])
@ -337,8 +328,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
AccountView.render("show.json", %{ AccountView.render("show.json", %{
user: user, user: user,
for: opts[:for], for: opts[:for],
relationships: opts[:relationships], skip_relationships: true
skip_relationships: opts[:skip_relationships]
}), }),
in_reply_to_id: reply_to && to_string(reply_to.id), in_reply_to_id: reply_to && to_string(reply_to.id),
in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id), in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id),

View File

@ -6,7 +6,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, import Pleroma.Web.ControllerHelper,
only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2, skip_relationships?: 1] only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2]
alias Ecto.Changeset alias Ecto.Changeset
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@ -139,8 +139,7 @@ def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: for_user, for: for_user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end

View File

@ -5,7 +5,7 @@
defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1] import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Conversation.Participation alias Pleroma.Conversation.Participation
@ -151,8 +151,7 @@ def conversation_statuses(
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
else else
_error -> _error ->
@ -207,7 +206,7 @@ def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"id" => notif
end end
end end
def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id} = params) do def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id}) do
with notifications <- Notification.set_read_up_to(user, max_id) do with notifications <- Notification.set_read_up_to(user, max_id) do
notifications = Enum.take(notifications, 80) notifications = Enum.take(notifications, 80)
@ -215,8 +214,7 @@ def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => m
|> put_view(NotificationView) |> put_view(NotificationView)
|> render("index.json", |> render("index.json",
notifications: notifications, notifications: notifications,
for: user, for: user
skip_relationships: skip_relationships?(params)
) )
end end
end end

View File

@ -20,7 +20,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
describe "home" do describe "home" do
setup do: oauth_access(["read:statuses"]) setup do: oauth_access(["read:statuses"])
test "does NOT render account/pleroma/relationship by default", %{ test "does NOT embed account/pleroma/relationship in statuses", %{
user: user, user: user,
conn: conn conn: conn
} do } do
@ -39,84 +39,6 @@ test "does NOT render account/pleroma/relationship by default", %{
end) end)
end end
test "embeds account relationships with `with_relationships=true`", %{user: user, conn: conn} do
uri = "/api/v1/timelines/home?with_relationships=true"
following = insert(:user, nickname: "followed")
third_user = insert(:user, nickname: "repeated")
{:ok, _activity} = CommonAPI.post(following, %{"status" => "post"})
{:ok, activity} = CommonAPI.post(third_user, %{"status" => "repeated post"})
{:ok, _, _} = CommonAPI.repeat(activity.id, following)
ret_conn = get(conn, uri)
assert Enum.empty?(json_response(ret_conn, :ok))
{:ok, _user} = User.follow(user, following)
ret_conn = get(conn, uri)
assert [
%{
"reblog" => %{
"content" => "repeated post",
"account" => %{
"pleroma" => %{
"relationship" => %{"following" => false, "followed_by" => false}
}
}
},
"account" => %{
"pleroma" => %{
"relationship" => %{"following" => true}
}
}
},
%{
"content" => "post",
"account" => %{
"acct" => "followed",
"pleroma" => %{
"relationship" => %{"following" => true}
}
}
}
] = json_response(ret_conn, :ok)
{:ok, _user} = User.follow(third_user, user)
ret_conn = get(conn, uri)
assert [
%{
"reblog" => %{
"content" => "repeated post",
"account" => %{
"acct" => "repeated",
"pleroma" => %{
"relationship" => %{"following" => false, "followed_by" => true}
}
}
},
"account" => %{
"pleroma" => %{
"relationship" => %{"following" => true}
}
}
},
%{
"content" => "post",
"account" => %{
"acct" => "followed",
"pleroma" => %{
"relationship" => %{"following" => true}
}
}
}
] = json_response(ret_conn, :ok)
end
test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do
{:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"}) {:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"})
{:ok, direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"}) {:ok, direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"})