Merge branch 'develop' into issue/1276

This commit is contained in:
Maksim Pechnikov 2020-04-13 21:19:27 +03:00
commit a16b3dbcbf
66 changed files with 1102 additions and 291 deletions

View file

@ -6,7 +6,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper,
only: [add_link_headers: 2, truthy_param?: 1, assign_account_by_id: 2, json_response: 3]
only: [
add_link_headers: 2,
truthy_param?: 1,
assign_account_by_id: 2,
json_response: 3,
skip_relationships?: 1
]
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Plugs.RateLimiter
@ -237,7 +243,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
conn
|> add_link_headers(activities)
|> put_view(StatusView)
|> render("index.json", activities: activities, for: reading_user, as: :activity)
|> render("index.json",
activities: activities,
for: reading_user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
else
_e -> render_error(conn, :not_found, "Can't find user")
end

View file

@ -14,17 +14,20 @@ defmodule Pleroma.Web.MastodonAPI.AppController do
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
plug(OAuthScopesPlug, %{scopes: ["read"]} when action == :verify_credentials)
plug(OpenApiSpex.Plug.CastAndValidate)
@local_mastodon_name "Mastodon-Local"
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.AppOperation
@doc "POST /api/v1/apps"
def create(conn, params) do
def create(%{body_params: params} = conn, _params) do
scopes = Scopes.fetch_scopes(params, ["read"])
app_attrs =
params
|> Map.drop(["scope", "scopes"])
|> Map.put("scopes", scopes)
|> Map.take([:client_name, :redirect_uris, :website])
|> Map.put(:scopes, scopes)
with cs <- App.register_changeset(%App{}, app_attrs),
false <- cs.changes[:client_name] == @local_mastodon_name,

View file

@ -5,7 +5,7 @@
defmodule Pleroma.Web.MastodonAPI.NotificationController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1]
alias Pleroma.Notification
alias Pleroma.Plugs.OAuthScopesPlug
@ -45,7 +45,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
conn
|> add_link_headers(notifications)
|> render("index.json", notifications: notifications, for: user)
|> render("index.json",
notifications: notifications,
for: user,
skip_relationships: skip_relationships?(params)
)
end
# GET /api/v1/notifications/:id
@ -66,7 +70,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
json(conn, %{})
end
# POST /api/v1/notifications/dismiss
# POST /api/v1/notifications/:id/dismiss
# POST /api/v1/notifications/dismiss (deprecated)
def dismiss(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
with {:ok, _notif} <- Notification.dismiss(user, id) do
json(conn, %{})

View file

@ -5,13 +5,14 @@
defmodule Pleroma.Web.MastodonAPI.SearchController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [fetch_integer_param: 2, skip_relationships?: 1]
alias Pleroma.Activity
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Plugs.RateLimiter
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web
alias Pleroma.Web.ControllerHelper
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.StatusView
@ -66,10 +67,11 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
defp search_options(params, user) do
[
skip_relationships: skip_relationships?(params),
resolve: params["resolve"] == "true",
following: params["following"] == "true",
limit: ControllerHelper.fetch_integer_param(params, "limit"),
offset: ControllerHelper.fetch_integer_param(params, "offset"),
limit: fetch_integer_param(params, "limit"),
offset: fetch_integer_param(params, "offset"),
type: params["type"],
author: get_author(params),
for_user: user
@ -79,12 +81,24 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
defp resource_search(_, "accounts", query, options) do
accounts = with_fallback(fn -> User.search(query, options) end)
AccountView.render("index.json", users: accounts, for: options[:for_user], as: :user)
AccountView.render("index.json",
users: accounts,
for: options[:for_user],
as: :user,
skip_relationships: false
)
end
defp resource_search(_, "statuses", query, options) do
statuses = with_fallback(fn -> Activity.search(options[:for_user], query, options) end)
StatusView.render("index.json", activities: statuses, for: options[:for_user], as: :activity)
StatusView.render("index.json",
activities: statuses,
for: options[:for_user],
as: :activity,
skip_relationships: options[:skip_relationships]
)
end
defp resource_search(:v2, "hashtags", query, _options) do

View file

@ -5,7 +5,8 @@
defmodule Pleroma.Web.MastodonAPI.StatusController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [try_render: 3, add_link_headers: 2]
import Pleroma.Web.ControllerHelper,
only: [try_render: 3, add_link_headers: 2, skip_relationships?: 1]
require Ecto.Query
@ -101,7 +102,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
`ids` query param is required
"""
def index(%{assigns: %{user: user}} = conn, %{"ids" => ids}) do
def index(%{assigns: %{user: user}} = conn, %{"ids" => ids} = params) do
limit = 100
activities =
@ -110,7 +111,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|> Activity.all_by_ids_with_object()
|> Enum.filter(&Visibility.visible_for_user?(&1, user))
render(conn, "index.json", activities: activities, for: user, as: :activity)
render(conn, "index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
end
@doc """
@ -360,7 +366,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
conn
|> add_link_headers(activities)
|> render("index.json", activities: activities, for: user, as: :activity)
|> render("index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
end
@doc "GET /api/v1/bookmarks"
@ -378,6 +389,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
conn
|> add_link_headers(bookmarks)
|> render("index.json", %{activities: activities, for: user, as: :activity})
|> render("index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
end
end

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper,
only: [add_link_headers: 2, add_link_headers: 3, truthy_param?: 1]
only: [add_link_headers: 2, add_link_headers: 3, truthy_param?: 1, skip_relationships?: 1]
alias Pleroma.Pagination
alias Pleroma.Plugs.OAuthScopesPlug
@ -14,9 +14,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
# TODO: Replace with a macro when there is a Phoenix release with
# TODO: Replace with a macro when there is a Phoenix release with the following commit in it:
# https://github.com/phoenixframework/phoenix/commit/2e8c63c01fec4dde5467dbbbf9705ff9e780735e
# in it
plug(RateLimiter, [name: :timeline, bucket_name: :direct_timeline] when action == :direct)
plug(RateLimiter, [name: :timeline, bucket_name: :public_timeline] when action == :public)
@ -49,7 +48,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
conn
|> add_link_headers(activities)
|> render("index.json", activities: activities, for: user, as: :activity)
|> render("index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
end
# GET /api/v1/timelines/direct
@ -68,7 +72,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
conn
|> add_link_headers(activities)
|> render("index.json", activities: activities, for: user, as: :activity)
|> render("index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
end
# GET /api/v1/timelines/public
@ -95,7 +104,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
conn
|> add_link_headers(activities, %{"local" => local_only})
|> render("index.json", activities: activities, for: user, as: :activity)
|> render("index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
else
render_error(conn, :unauthorized, "authorization required for timeline view")
end
@ -140,7 +154,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
conn
|> add_link_headers(activities, %{"local" => local_only})
|> render("index.json", activities: activities, for: user, as: :activity)
|> render("index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
end
# GET /api/v1/timelines/list/:list_id
@ -164,7 +183,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> ActivityPub.fetch_activities_bounded(following, params)
|> Enum.reverse()
render(conn, "index.json", activities: activities, for: user, as: :activity)
render(conn, "index.json",
activities: activities,
for: user,
as: :activity,
skip_relationships: skip_relationships?(params)
)
else
_e -> render_error(conn, :forbidden, "Error.")
end

View file

@ -15,6 +15,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
def render("index.json", %{users: users} = opts) do
reading_user = opts[:for]
# Note: :skip_relationships option is currently intentionally not supported for accounts
relationships_opt =
cond do
Map.has_key?(opts, :relationships) ->
@ -73,7 +74,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
followed_by =
if following_relationships do
case FollowingRelationship.find(following_relationships, target, reading_user) do
%{state: "accept"} -> true
%{state: :follow_accept} -> true
_ -> false
end
else
@ -83,7 +84,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
# NOTE: adjust UserRelationship.view_relationships_option/2 on new relation-related flags
%{
id: to_string(target.id),
following: follow_state == "accept",
following: follow_state == :follow_accept,
followed_by: followed_by,
blocking:
UserRelationship.exists?(
@ -125,7 +126,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
reading_user,
&User.subscribed_to?(&2, &1)
),
requested: follow_state == "pending",
requested: follow_state == :follow_pending,
domain_blocking: User.blocks_domain?(reading_user, target),
showing_reblogs:
not UserRelationship.exists?(
@ -192,11 +193,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
end)
relationship =
render("relationship.json", %{
user: opts[:for],
target: user,
relationships: opts[:relationships]
})
if opts[:skip_relationships] do
%{}
else
render("relationship.json", %{
user: opts[:for],
target: user,
relationships: opts[:relationships]
})
end
%{
id: to_string(user.id),

View file

@ -51,14 +51,15 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
|> Enum.filter(& &1)
|> Kernel.++(move_activities_targets)
UserRelationship.view_relationships_option(reading_user, actors)
UserRelationship.view_relationships_option(reading_user, actors,
source_mutes_only: opts[:skip_relationships]
)
end
opts = %{
for: reading_user,
parent_activities: parent_activities,
relationships: relationships_opt
}
opts =
opts
|> Map.put(:parent_activities, parent_activities)
|> Map.put(:relationships, relationships_opt)
safe_render_many(notifications, NotificationView, "show.json", opts)
end
@ -82,12 +83,16 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
mastodon_type = Activity.mastodon_notification_type(activity)
render_opts = %{
relationships: opts[:relationships],
skip_relationships: opts[:skip_relationships]
}
with %{id: _} = account <-
AccountView.render("show.json", %{
user: actor,
for: reading_user,
relationships: opts[:relationships]
}) do
AccountView.render(
"show.json",
Map.merge(render_opts, %{user: actor, for: reading_user})
) do
response = %{
id: to_string(notification.id),
type: mastodon_type,
@ -98,8 +103,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
}
}
render_opts = %{relationships: opts[:relationships]}
case mastodon_type do
"mention" ->
put_status(response, activity, reading_user, render_opts)
@ -111,6 +114,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
put_status(response, parent_activity_fn.(), reading_user, render_opts)
"move" ->
# Note: :skip_relationships option being applied to _account_ rendering (here)
put_target(response, activity, reading_user, render_opts)
"follow" ->

View file

@ -99,7 +99,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
true ->
actors = Enum.map(activities ++ parent_activities, &get_user(&1.data["actor"]))
UserRelationship.view_relationships_option(reading_user, actors)
UserRelationship.view_relationships_option(reading_user, actors,
source_mutes_only: opts[:skip_relationships]
)
end
opts =
@ -153,7 +155,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
AccountView.render("show.json", %{
user: user,
for: opts[:for],
relationships: opts[:relationships]
relationships: opts[:relationships],
skip_relationships: opts[:skip_relationships]
}),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
@ -301,6 +304,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
_ -> []
end
# Status muted state (would do 1 request per status unless user mutes are preloaded)
muted =
thread_muted? ||
UserRelationship.exists?(
@ -319,7 +323,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
AccountView.render("show.json", %{
user: user,
for: opts[:for],
relationships: opts[:relationships]
relationships: opts[:relationships],
skip_relationships: opts[:skip_relationships]
}),
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),