Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into emoji-reaction-extensions

This commit is contained in:
lain 2020-01-20 18:10:55 +01:00
commit 7d8b709d29
15 changed files with 45 additions and 29 deletions

View file

@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Mastodon API, streaming: Add `pleroma.direct_conversation_id` to the `conversation` stream event payload. - Mastodon API, streaming: Add `pleroma.direct_conversation_id` to the `conversation` stream event payload.
- Admin API: Render whole status in grouped reports - Admin API: Render whole status in grouped reports
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise). - Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise).
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try.
</details> </details>
### Added ### Added

View file

@ -20,7 +20,7 @@ def filter(%{"type" => message_type} = message) do
with accepted_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :accept]), with accepted_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :accept]),
rejected_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :reject]), rejected_vocabulary <- Pleroma.Config.get([:mrf_vocabulary, :reject]),
true <- true <-
length(accepted_vocabulary) == 0 || Enum.member?(accepted_vocabulary, message_type), Enum.empty?(accepted_vocabulary) || Enum.member?(accepted_vocabulary, message_type),
false <- false <-
length(rejected_vocabulary) > 0 && Enum.member?(rejected_vocabulary, message_type), length(rejected_vocabulary) > 0 && Enum.member?(rejected_vocabulary, message_type),
{:ok, _} <- filter(message["object"]) do {:ok, _} <- filter(message["object"]) do

View file

@ -639,7 +639,7 @@ def get_password_reset(conn, %{"nickname" => nickname}) do
def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
users = nicknames |> Enum.map(&User.get_cached_by_nickname/1) users = nicknames |> Enum.map(&User.get_cached_by_nickname/1)
Enum.map(users, &User.force_password_reset_async/1) Enum.each(users, &User.force_password_reset_async/1)
ModerationLog.insert_log(%{ ModerationLog.insert_log(%{
actor: admin, actor: admin,

View file

@ -85,9 +85,13 @@ def delete(activity_id, user) do
def repeat(id_or_ap_id, user, params \\ %{}) do def repeat(id_or_ap_id, user, params \\ %{}) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
object <- Object.normalize(activity), object <- Object.normalize(activity),
nil <- Utils.get_existing_announce(user.ap_id, object), announce_activity <- Utils.get_existing_announce(user.ap_id, object),
public <- public_announce?(object, params) do public <- public_announce?(object, params) do
if announce_activity do
{:ok, announce_activity, object}
else
ActivityPub.announce(user, object, nil, true, public) ActivityPub.announce(user, object, nil, true, public)
end
else else
_ -> {:error, dgettext("errors", "Could not repeat")} _ -> {:error, dgettext("errors", "Could not repeat")}
end end
@ -105,8 +109,12 @@ def unrepeat(id_or_ap_id, user) do
def favorite(id_or_ap_id, user) do def favorite(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id), with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
object <- Object.normalize(activity), object <- Object.normalize(activity),
nil <- Utils.get_existing_like(user.ap_id, object) do like_activity <- Utils.get_existing_like(user.ap_id, object) do
if like_activity do
{:ok, like_activity, object}
else
ActivityPub.like(user, object) ActivityPub.like(user, object)
end
else else
_ -> {:error, dgettext("errors", "Could not favorite")} _ -> {:error, dgettext("errors", "Could not favorite")}
end end

View file

@ -6,9 +6,9 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionController do
@moduledoc "The module represents functions to manage user subscriptions." @moduledoc "The module represents functions to manage user subscriptions."
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View
alias Pleroma.Web.Push alias Pleroma.Web.Push
alias Pleroma.Web.Push.Subscription alias Pleroma.Web.Push.Subscription
alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View
action_fallback(:errors) action_fallback(:errors)

View file

@ -14,10 +14,10 @@ defmodule Pleroma.Web.OAuth.OAuthController do
alias Pleroma.Web.ControllerHelper alias Pleroma.Web.ControllerHelper
alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Scopes
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken alias Pleroma.Web.OAuth.Token.Strategy.RefreshToken
alias Pleroma.Web.OAuth.Token.Strategy.Revoke, as: RevokeToken alias Pleroma.Web.OAuth.Token.Strategy.Revoke, as: RevokeToken
alias Pleroma.Web.OAuth.Scopes
require Logger require Logger

View file

@ -124,7 +124,7 @@ defp deps do
{:earmark, "~> 1.3"}, {:earmark, "~> 1.3"},
{:bbcode, "~> 0.1.1"}, {:bbcode, "~> 0.1.1"},
{:ex_machina, "~> 2.3", only: :test}, {:ex_machina, "~> 2.3", only: :test},
{:credo, "~> 0.9.3", only: [:dev, :test]}, {:credo, "~> 1.1.0", only: [:dev, :test], runtime: false},
{:mock, "~> 0.3.3", only: :test}, {:mock, "~> 0.3.3", only: :test},
{:crypt, {:crypt,
git: "https://github.com/msantos/crypt", ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"}, git: "https://github.com/msantos/crypt", ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"},

View file

@ -16,7 +16,7 @@
"cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, "cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm"}, "cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm"},
"credo": {:hex, :credo, "0.9.3", "76fa3e9e497ab282e0cf64b98a624aa11da702854c52c82db1bf24e54ab7c97a", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "1.1.5", "caec7a3cadd2e58609d7ee25b3931b129e739e070539ad1a0cd7efeeb47014f4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]}, "crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm"}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm"},

View file

@ -745,7 +745,7 @@ test "it doesn't return notifications from a blocked user when with_muted is set
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"}) {:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 0 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
end end
test "it doesn't return notifications from a domain-blocked user when with_muted is set" do test "it doesn't return notifications from a domain-blocked user when with_muted is set" do
@ -755,7 +755,7 @@ test "it doesn't return notifications from a domain-blocked user when with_muted
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"}) {:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 0 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
end end
test "it returns notifications from muted threads when with_muted is set" do test "it returns notifications from muted threads when with_muted is set" do

View file

@ -78,7 +78,7 @@ test "with locked accounts, it does not create a follow or an accept" do
) )
|> Repo.all() |> Repo.all()
assert length(accepts) == 0 assert Enum.empty?(accepts)
end end
test "it works for follow requests when you are already followed, creating a new accept activity" do test "it works for follow requests when you are already followed, creating a new accept activity" do

View file

@ -1363,9 +1363,9 @@ test "returns 404 when report id is invalid", %{conn: conn} do
} }
end end
test "requires write:reports scope", %{conn: conn, id: id, admin: admin} do test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
read_token = insert(:oauth_token, user: admin, scopes: ["read"]) read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
write_token = insert(:oauth_token, user: admin, scopes: ["write:reports"]) write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
response = response =
conn conn
@ -1376,7 +1376,7 @@ test "requires write:reports scope", %{conn: conn, id: id, admin: admin} do
|> json_response(403) |> json_response(403)
assert response == %{ assert response == %{
"error" => "Insufficient permissions: admin:write:reports | write:reports." "error" => "Insufficient permissions: admin:write:reports."
} }
conn conn
@ -2864,7 +2864,7 @@ test "GET /instances/:instance/statuses", %{conn: conn} do
response = json_response(ret_conn, 200) response = json_response(ret_conn, 200)
assert length(response) == 0 assert Enum.empty?(response)
end end
end end

View file

@ -284,22 +284,22 @@ test "favoriting a status" do
{:ok, %Activity{}, _} = CommonAPI.favorite(activity.id, user) {:ok, %Activity{}, _} = CommonAPI.favorite(activity.id, user)
end end
test "retweeting a status twice returns an error" do test "retweeting a status twice returns the status" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
{:ok, %Activity{}, _object} = CommonAPI.repeat(activity.id, user) {:ok, %Activity{} = activity, object} = CommonAPI.repeat(activity.id, user)
{:error, _} = CommonAPI.repeat(activity.id, user) {:ok, ^activity, ^object} = CommonAPI.repeat(activity.id, user)
end end
test "favoriting a status twice returns an error" do test "favoriting a status twice returns the status" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
{:ok, %Activity{}, _object} = CommonAPI.favorite(activity.id, user) {:ok, %Activity{} = activity, object} = CommonAPI.favorite(activity.id, user)
{:error, _} = CommonAPI.favorite(activity.id, user) {:ok, ^activity, ^object} = CommonAPI.favorite(activity.id, user)
end end
end end

View file

@ -307,7 +307,7 @@ test "for private posts, not a reply" do
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "private", nil) {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "private", nil)
assert length(to) == 2 assert length(to) == 2
assert length(cc) == 0 assert Enum.empty?(cc)
assert mentioned_user.ap_id in to assert mentioned_user.ap_id in to
assert user.follower_address in to assert user.follower_address in to
@ -323,7 +323,7 @@ test "for private posts, a reply" do
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private", nil) {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private", nil)
assert length(to) == 3 assert length(to) == 3
assert length(cc) == 0 assert Enum.empty?(cc)
assert mentioned_user.ap_id in to assert mentioned_user.ap_id in to
assert third_user.ap_id in to assert third_user.ap_id in to
@ -338,7 +338,7 @@ test "for direct posts, not a reply" do
{to, cc} = Utils.get_to_and_cc(user, mentions, nil, "direct", nil) {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "direct", nil)
assert length(to) == 1 assert length(to) == 1
assert length(cc) == 0 assert Enum.empty?(cc)
assert mentioned_user.ap_id in to assert mentioned_user.ap_id in to
end end
@ -353,7 +353,7 @@ test "for direct posts, a reply" do
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct", nil) {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct", nil)
assert length(to) == 2 assert length(to) == 2
assert length(cc) == 0 assert Enum.empty?(cc)
assert mentioned_user.ap_id in to assert mentioned_user.ap_id in to
assert third_user.ap_id in to assert third_user.ap_id in to

View file

@ -638,6 +638,13 @@ test "favs a status and returns it", %{conn: conn} do
assert to_string(activity.id) == id assert to_string(activity.id) == id
end end
test "favoriting twice will just return 200", %{conn: conn} do
activity = insert(:note_activity)
post(conn, "/api/v1/statuses/#{activity.id}/favourite")
assert post(conn, "/api/v1/statuses/#{activity.id}/favourite") |> json_response(200)
end
test "returns 400 error for a wrong id", %{conn: conn} do test "returns 400 error for a wrong id", %{conn: conn} do
conn = post(conn, "/api/v1/statuses/1/favourite") conn = post(conn, "/api/v1/statuses/1/favourite")

View file

@ -55,7 +55,7 @@ test "it returns HTTP 200", %{conn: conn} do
user = refresh_record(user) user = refresh_record(user)
assert Comeonin.Pbkdf2.checkpw("test", user.password_hash) assert Comeonin.Pbkdf2.checkpw("test", user.password_hash)
assert length(Token.get_user_tokens(user)) == 0 assert Enum.empty?(Token.get_user_tokens(user))
end end
test "it sets password_reset_pending to false", %{conn: conn} do test "it sets password_reset_pending to false", %{conn: conn} do