From 26e2076659450361b4fd4252c7a7b838099c442b Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Tue, 10 Mar 2020 18:11:48 +0300 Subject: [PATCH 01/17] fix for feed page pagination --- lib/pleroma/web/controller_helper.ex | 7 ++-- lib/pleroma/web/feed/tag_controller.ex | 4 +- lib/pleroma/web/feed/user_controller.ex | 4 +- test/web/feed/tag_controller_test.exs | 52 +++++++++++++++++++------ test/web/feed/user_controller_test.exs | 15 ++++++- 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/lib/pleroma/web/controller_helper.ex b/lib/pleroma/web/controller_helper.ex index c9a3a2585..ad293cda9 100644 --- a/lib/pleroma/web/controller_helper.ex +++ b/lib/pleroma/web/controller_helper.ex @@ -87,7 +87,8 @@ def try_render(conn, _, _) do render_error(conn, :not_implemented, "Can't display this activity") end - @spec put_in_if_exist(map(), atom() | String.t(), any) :: map() - def put_in_if_exist(map, _key, nil), do: map - def put_in_if_exist(map, key, value), do: put_in(map, key, value) + @spec put_if_exist(map(), atom() | String.t(), any) :: map() + def put_if_exist(map, _key, nil), do: map + + def put_if_exist(map, key, value), do: Map.put(map, key, value) end diff --git a/lib/pleroma/web/feed/tag_controller.ex b/lib/pleroma/web/feed/tag_controller.ex index 75c9ea17e..904047b12 100644 --- a/lib/pleroma/web/feed/tag_controller.ex +++ b/lib/pleroma/web/feed/tag_controller.ex @@ -9,14 +9,14 @@ defmodule Pleroma.Web.Feed.TagController do alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.Feed.FeedView - import Pleroma.Web.ControllerHelper, only: [put_in_if_exist: 3] + import Pleroma.Web.ControllerHelper, only: [put_if_exist: 3] def feed(conn, %{"tag" => raw_tag} = params) do {format, tag} = parse_tag(raw_tag) activities = %{"type" => ["Create"], "tag" => tag} - |> put_in_if_exist("max_id", params["max_id"]) + |> put_if_exist("max_id", params["max_id"]) |> ActivityPub.fetch_public_activities() conn diff --git a/lib/pleroma/web/feed/user_controller.ex b/lib/pleroma/web/feed/user_controller.ex index 9ba602d9f..9ffb3b9be 100644 --- a/lib/pleroma/web/feed/user_controller.ex +++ b/lib/pleroma/web/feed/user_controller.ex @@ -11,7 +11,7 @@ defmodule Pleroma.Web.Feed.UserController do alias Pleroma.Web.ActivityPub.ActivityPubController alias Pleroma.Web.Feed.FeedView - import Pleroma.Web.ControllerHelper, only: [put_in_if_exist: 3] + import Pleroma.Web.ControllerHelper, only: [put_if_exist: 3] plug(Pleroma.Plugs.SetFormatPlug when action in [:feed_redirect]) @@ -46,7 +46,7 @@ def feed(conn, %{"nickname" => nickname} = params) do "type" => ["Create"], "actor_id" => user.ap_id } - |> put_in_if_exist("max_id", params["max_id"]) + |> put_if_exist("max_id", params["max_id"]) |> ActivityPub.fetch_public_activities() conn diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs index 5950605e8..c774bd420 100644 --- a/test/web/feed/tag_controller_test.exs +++ b/test/web/feed/tag_controller_test.exs @@ -8,6 +8,8 @@ defmodule Pleroma.Web.Feed.TagControllerTest do import Pleroma.Factory import SweetXml + alias Pleroma.Object + alias Pleroma.Web.CommonAPI alias Pleroma.Web.Feed.FeedView clear_config([:feed]) @@ -19,9 +21,9 @@ test "gets a feed (ATOM)", %{conn: conn} do ) user = insert(:user) - {:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"}) + {:ok, activity1} = CommonAPI.post(user, %{"status" => "yeah #PleromaArt"}) - object = Pleroma.Object.normalize(activity1) + object = Object.normalize(activity1) object_data = Map.put(object.data, "attachment", [ @@ -41,10 +43,9 @@ test "gets a feed (ATOM)", %{conn: conn} do |> Ecto.Changeset.change(data: object_data) |> Pleroma.Repo.update() - {:ok, _activity2} = - Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"}) + {:ok, activity2} = CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"}) - {:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"}) + {:ok, _activity3} = CommonAPI.post(user, %{"status" => "This is :moominmamma"}) response = conn @@ -63,6 +64,20 @@ test "gets a feed (ATOM)", %{conn: conn} do assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname] assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id] + + resp = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get("/tags/pleromaart.atom", %{"max_id" => activity2.id}) + |> response(200) + + xml = parse(resp) + + assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart' + + assert xpath(xml, ~x"//feed/entry/title/text()"l) == [ + 'yeah #PleromaArt' + ] end test "gets a feed (RSS)", %{conn: conn} do @@ -72,9 +87,9 @@ test "gets a feed (RSS)", %{conn: conn} do ) user = insert(:user) - {:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"}) + {:ok, activity1} = CommonAPI.post(user, %{"status" => "yeah #PleromaArt"}) - object = Pleroma.Object.normalize(activity1) + object = Object.normalize(activity1) object_data = Map.put(object.data, "attachment", [ @@ -94,10 +109,9 @@ test "gets a feed (RSS)", %{conn: conn} do |> Ecto.Changeset.change(data: object_data) |> Pleroma.Repo.update() - {:ok, activity2} = - Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"}) + {:ok, activity2} = CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"}) - {:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"}) + {:ok, _activity3} = CommonAPI.post(user, %{"status" => "This is :moominmamma"}) response = conn @@ -131,8 +145,8 @@ test "gets a feed (RSS)", %{conn: conn} do "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4" ] - obj1 = Pleroma.Object.normalize(activity1) - obj2 = Pleroma.Object.normalize(activity2) + obj1 = Object.normalize(activity1) + obj2 = Object.normalize(activity2) assert xpath(xml, ~x"//channel/item/description/text()"sl) == [ HtmlEntities.decode(FeedView.activity_content(obj2)), @@ -150,5 +164,19 @@ test "gets a feed (RSS)", %{conn: conn} do assert xpath(xml, ~x"//channel/description/text()"s) == "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse." + + resp = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get("/tags/pleromaart", %{"max_id" => activity2.id}) + |> response(200) + + xml = parse(resp) + + assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart' + + assert xpath(xml, ~x"//channel/item/title/text()"l) == [ + 'yeah #PleromaArt' + ] end end diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs index 00c50f003..fd59ca892 100644 --- a/test/web/feed/user_controller_test.exs +++ b/test/web/feed/user_controller_test.exs @@ -54,7 +54,7 @@ test "gets a feed", %{conn: conn} do } ) - _note_activity2 = insert(:note_activity, note: note2) + note_activity2 = insert(:note_activity, note: note2) object = Object.normalize(note_activity) resp = @@ -70,6 +70,19 @@ test "gets a feed", %{conn: conn} do assert activity_titles == ['42 This...', 'This is...'] assert resp =~ object.data["content"] + + resp = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id}) + |> response(200) + + activity_titles = + resp + |> SweetXml.parse() + |> SweetXml.xpath(~x"//entry/title/text()"l) + + assert activity_titles == ['This is...'] end test "returns 404 for a missing feed", %{conn: conn} do From 91870c8995c154839d611bcce6d038f72ef0665c Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Fri, 13 Mar 2020 17:41:26 +0300 Subject: [PATCH 02/17] adding rss for user feed --- lib/pleroma/web/feed/user_controller.ex | 13 +++- lib/pleroma/web/router.ex | 2 +- .../{_activity.xml.eex => _activity.atom.eex} | 0 .../web/templates/feed/feed/_activity.rss.eex | 49 ++++++++++++ .../{_author.xml.eex => _author.atom.eex} | 0 .../web/templates/feed/feed/_author.rss.eex | 17 +++++ .../feed/feed/{user.xml.eex => user.atom.eex} | 4 +- .../web/templates/feed/feed/user.rss.eex | 20 +++++ test/web/feed/user_controller_test.exs | 74 ++++++++++++++++++- 9 files changed, 170 insertions(+), 9 deletions(-) rename lib/pleroma/web/templates/feed/feed/{_activity.xml.eex => _activity.atom.eex} (100%) create mode 100644 lib/pleroma/web/templates/feed/feed/_activity.rss.eex rename lib/pleroma/web/templates/feed/feed/{_author.xml.eex => _author.atom.eex} (100%) create mode 100644 lib/pleroma/web/templates/feed/feed/_author.rss.eex rename lib/pleroma/web/templates/feed/feed/{user.xml.eex => user.atom.eex} (85%) create mode 100644 lib/pleroma/web/templates/feed/feed/user.rss.eex diff --git a/lib/pleroma/web/feed/user_controller.ex b/lib/pleroma/web/feed/user_controller.ex index 9ffb3b9be..e27f85929 100644 --- a/lib/pleroma/web/feed/user_controller.ex +++ b/lib/pleroma/web/feed/user_controller.ex @@ -40,6 +40,15 @@ def feed_redirect(conn, %{"nickname" => nickname}) do end def feed(conn, %{"nickname" => nickname} = params) do + format = get_format(conn) + + format = + if format in ["rss", "atom"] do + format + else + "atom" + end + with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do activities = %{ @@ -50,9 +59,9 @@ def feed(conn, %{"nickname" => nickname} = params) do |> ActivityPub.fetch_public_activities() conn - |> put_resp_content_type("application/atom+xml") + |> put_resp_content_type("application/#{format}+xml") |> put_view(FeedView) - |> render("user.xml", + |> render("user.#{format}", user: user, activities: activities, feed_config: Pleroma.Config.get([:feed]) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index e4e3ee704..3f36f6c1a 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -513,7 +513,7 @@ defmodule Pleroma.Web.Router do end pipeline :ostatus do - plug(:accepts, ["html", "xml", "atom", "activity+json", "json"]) + plug(:accepts, ["html", "xml", "rss", "atom", "activity+json", "json"]) plug(Pleroma.Plugs.StaticFEPlug) end diff --git a/lib/pleroma/web/templates/feed/feed/_activity.xml.eex b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex similarity index 100% rename from lib/pleroma/web/templates/feed/feed/_activity.xml.eex rename to lib/pleroma/web/templates/feed/feed/_activity.atom.eex diff --git a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex new file mode 100644 index 000000000..a4dbed638 --- /dev/null +++ b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex @@ -0,0 +1,49 @@ + + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post + <%= @data["id"] %> + <%= activity_title(@object, Keyword.get(@feed_config, :post_title, %{})) %> + <%= activity_content(@object) %> + <%= @data["published"] %> + <%= @data["published"] %> + + <%= activity_context(@activity) %> + + <%= activity_context(@activity) %> + + <%= if @data["summary"] do %> + <%= @data["summary"] %> + <% end %> + + <%= if @activity.local do %> + <%= @data["id"] %> + <% else %> + <%= @data["external_url"] %> + <% end %> + + <%= for tag <- @data["tag"] || [] do %> + + <% end %> + + <%= for attachment <- @data["attachment"] || [] do %> + <%= attachment_href(attachment) %> + <% end %> + + <%= if @data["inReplyTo"] do %> + + <% end %> + + <%= for id <- @activity.recipients do %> + <%= if id == Pleroma.Constants.as_public() do %> + http://activityschema.org/collection/public + <% else %> + <%= unless Regex.match?(~r/^#{Pleroma.Web.base_url()}.+followers$/, id) do %> + <%= id %> + <% end %> + <% end %> + <% end %> + + <%= for {emoji, file} <- @data["emoji"] || %{} do %> + <%= file %> + <% end %> + diff --git a/lib/pleroma/web/templates/feed/feed/_author.xml.eex b/lib/pleroma/web/templates/feed/feed/_author.atom.eex similarity index 100% rename from lib/pleroma/web/templates/feed/feed/_author.xml.eex rename to lib/pleroma/web/templates/feed/feed/_author.atom.eex diff --git a/lib/pleroma/web/templates/feed/feed/_author.rss.eex b/lib/pleroma/web/templates/feed/feed/_author.rss.eex new file mode 100644 index 000000000..526aeddcf --- /dev/null +++ b/lib/pleroma/web/templates/feed/feed/_author.rss.eex @@ -0,0 +1,17 @@ + + <%= @user.ap_id %> + http://activitystrea.ms/schema/1.0/person + <%= @user.ap_id %> + <%= @user.nickname %> + <%= @user.name %> + <%= escape(@user.bio) %> + <%= escape(@user.bio) %> + <%= @user.nickname %> + <%= User.avatar_url(@user) %> + <%= if User.banner_url(@user) do %> + <%= User.banner_url(@user) %> + <% end %> + <%= if @user.local do %> + true + <% end %> + diff --git a/lib/pleroma/web/templates/feed/feed/user.xml.eex b/lib/pleroma/web/templates/feed/feed/user.atom.eex similarity index 85% rename from lib/pleroma/web/templates/feed/feed/user.xml.eex rename to lib/pleroma/web/templates/feed/feed/user.atom.eex index d274c08ae..c6acd848f 100644 --- a/lib/pleroma/web/templates/feed/feed/user.xml.eex +++ b/lib/pleroma/web/templates/feed/feed/user.atom.eex @@ -12,13 +12,13 @@ <%= logo(@user) %> - <%= render @view_module, "_author.xml", assigns %> + <%= render @view_module, "_author.atom", assigns %> <%= if last_activity(@activities) do %> <% end %> <%= for activity <- @activities do %> - <%= render @view_module, "_activity.xml", Map.merge(assigns, prepare_activity(activity)) %> + <%= render @view_module, "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/user.rss.eex b/lib/pleroma/web/templates/feed/feed/user.rss.eex new file mode 100644 index 000000000..d69120480 --- /dev/null +++ b/lib/pleroma/web/templates/feed/feed/user.rss.eex @@ -0,0 +1,20 @@ + + + + <%= user_feed_url(@conn, :feed, @user.nickname) <> ".rss" %> + <%= @user.nickname <> "'s timeline" %> + <%= most_recent_update(@activities, @user) %> + <%= logo(@user) %> + <%= '#{user_feed_url(@conn, :feed, @user.nickname)}.rss' %> + + <%= render @view_module, "_author.rss", assigns %> + + <%= if last_activity(@activities) do %> + <%= '#{user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}' %> + <% end %> + + <%= for activity <- @activities do %> + <%= render @view_module, "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %> + <% end %> + + diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs index fd59ca892..e3dfa88f1 100644 --- a/test/web/feed/user_controller_test.exs +++ b/test/web/feed/user_controller_test.exs @@ -19,7 +19,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do describe "feed" do clear_config([:feed]) - test "gets a feed", %{conn: conn} do + test "gets an atom feed", %{conn: conn} do Config.put( [:feed, :post_title], %{max_length: 10, omission: "..."} @@ -59,7 +59,7 @@ test "gets a feed", %{conn: conn} do resp = conn - |> put_req_header("content-type", "application/atom+xml") + |> put_req_header("accept", "application/atom+xml") |> get(user_feed_path(conn, :feed, user.nickname)) |> response(200) @@ -73,7 +73,7 @@ test "gets a feed", %{conn: conn} do resp = conn - |> put_req_header("content-type", "application/atom+xml") + |> put_req_header("accept", "application/atom+xml") |> get("/users/#{user.nickname}/feed", %{"max_id" => note_activity2.id}) |> response(200) @@ -85,10 +85,76 @@ test "gets a feed", %{conn: conn} do assert activity_titles == ['This is...'] end + test "gets a rss feed", %{conn: conn} do + Pleroma.Config.put( + [:feed, :post_title], + %{max_length: 10, omission: "..."} + ) + + activity = insert(:note_activity) + + note = + insert(:note, + data: %{ + "content" => "This is :moominmamma: note ", + "attachment" => [ + %{ + "url" => [ + %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"} + ] + } + ], + "inReplyTo" => activity.data["id"] + } + ) + + note_activity = insert(:note_activity, note: note) + user = User.get_cached_by_ap_id(note_activity.data["actor"]) + + note2 = + insert(:note, + user: user, + data: %{ + "content" => "42 This is :moominmamma: note ", + "inReplyTo" => activity.data["id"] + } + ) + + note_activity2 = insert(:note_activity, note: note2) + object = Object.normalize(note_activity) + + resp = + conn + |> put_req_header("accept", "application/rss+xml") + |> get("/users/#{user.nickname}/feed.rss") + |> response(200) + + activity_titles = + resp + |> SweetXml.parse() + |> SweetXml.xpath(~x"//item/title/text()"l) + + assert activity_titles == ['42 This...', 'This is...'] + assert resp =~ object.data["content"] + + resp = + conn + |> put_req_header("accept", "application/atom+xml") + |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id}) + |> response(200) + + activity_titles = + resp + |> SweetXml.parse() + |> SweetXml.xpath(~x"//item/title/text()"l) + + assert activity_titles == ['This is...'] + end + test "returns 404 for a missing feed", %{conn: conn} do conn = conn - |> put_req_header("content-type", "application/atom+xml") + |> put_req_header("accept", "application/atom+xml") |> get(user_feed_path(conn, :feed, "nonexisting")) assert response(conn, 404) From 89e4b3ebbd433032a2687712c9c6684902fe4ebe Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Fri, 13 Mar 2020 17:58:14 +0300 Subject: [PATCH 03/17] fix for content-type header for tag feed --- lib/pleroma/web/feed/tag_controller.ex | 2 +- test/web/feed/tag_controller_test.exs | 22 ++++++++++++---------- test/web/feed/user_controller_test.exs | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/pleroma/web/feed/tag_controller.ex b/lib/pleroma/web/feed/tag_controller.ex index 904047b12..8133f8480 100644 --- a/lib/pleroma/web/feed/tag_controller.ex +++ b/lib/pleroma/web/feed/tag_controller.ex @@ -20,7 +20,7 @@ def feed(conn, %{"tag" => raw_tag} = params) do |> ActivityPub.fetch_public_activities() conn - |> put_resp_content_type("application/atom+xml") + |> put_resp_content_type("application/#{format}+xml") |> put_view(FeedView) |> render("tag.#{format}", activities: activities, diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs index c774bd420..da1caf049 100644 --- a/test/web/feed/tag_controller_test.exs +++ b/test/web/feed/tag_controller_test.exs @@ -49,7 +49,7 @@ test "gets a feed (ATOM)", %{conn: conn} do response = conn - |> put_req_header("content-type", "application/atom+xml") + |> put_req_header("accept", "application/atom+xml") |> get(tag_feed_path(conn, :feed, "pleromaart.atom")) |> response(200) @@ -65,12 +65,13 @@ test "gets a feed (ATOM)", %{conn: conn} do assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname] assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id] - resp = + conn = conn - |> put_req_header("content-type", "application/atom+xml") + |> put_req_header("accept", "application/atom+xml") |> get("/tags/pleromaart.atom", %{"max_id" => activity2.id}) - |> response(200) + assert get_resp_header(conn, "content-type") == ["application/atom+xml; charset=utf-8"] + resp = response(conn, 200) xml = parse(resp) assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart' @@ -115,7 +116,7 @@ test "gets a feed (RSS)", %{conn: conn} do response = conn - |> put_req_header("content-type", "application/rss+xml") + |> put_req_header("accept", "application/rss+xml") |> get(tag_feed_path(conn, :feed, "pleromaart.rss")) |> response(200) @@ -155,7 +156,7 @@ test "gets a feed (RSS)", %{conn: conn} do response = conn - |> put_req_header("content-type", "application/atom+xml") + |> put_req_header("accept", "application/rss+xml") |> get(tag_feed_path(conn, :feed, "pleromaart")) |> response(200) @@ -165,12 +166,13 @@ test "gets a feed (RSS)", %{conn: conn} do assert xpath(xml, ~x"//channel/description/text()"s) == "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse." - resp = + conn = conn - |> put_req_header("content-type", "application/atom+xml") - |> get("/tags/pleromaart", %{"max_id" => activity2.id}) - |> response(200) + |> put_req_header("accept", "application/rss+xml") + |> get("/tags/pleromaart.rss", %{"max_id" => activity2.id}) + assert get_resp_header(conn, "content-type") == ["application/rss+xml; charset=utf-8"] + resp = response(conn, 200) xml = parse(resp) assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart' diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs index e3dfa88f1..5c91c33d8 100644 --- a/test/web/feed/user_controller_test.exs +++ b/test/web/feed/user_controller_test.exs @@ -19,7 +19,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do describe "feed" do clear_config([:feed]) - test "gets an atom feed", %{conn: conn} do + test "gets a feed", %{conn: conn} do Config.put( [:feed, :post_title], %{max_length: 10, omission: "..."} @@ -139,7 +139,7 @@ test "gets a rss feed", %{conn: conn} do resp = conn - |> put_req_header("accept", "application/atom+xml") + |> put_req_header("accept", "application/rss+xml") |> get("/users/#{user.nickname}/feed.rss", %{"max_id" => note_activity2.id}) |> response(200) From 8dd01b24d2e64b61992ff9c6895c98f7f7052c6c Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Mon, 16 Mar 2020 11:44:53 -0500 Subject: [PATCH 04/17] Improve documentation of mrf_object_age --- docs/configuration/cheatsheet.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index 2629385da..4012fe9b1 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -138,7 +138,8 @@ config :pleroma, :mrf_user_allowlist, ``` #### :mrf_object_age -* `threshold`: Required age (in seconds) of a post before actions are taken. +* `threshold`: Required time offset (in seconds) compared to your server clock of an incoming post before actions are taken. + e.g., A value of 900 results in any post with a timestamp older than 15 minutes will be acted upon. * `actions`: A list of actions to apply to the post: * `:delist` removes the post from public timelines * `:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines From f3791add99014c4e5f1c51c06f8ace84b254cec2 Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Mon, 16 Mar 2020 20:05:21 +0300 Subject: [PATCH 05/17] removing with_move parameter --- CHANGELOG.md | 3 +++ docs/API/differences_in_mastoapi_responses.md | 1 - lib/pleroma/notification.ex | 9 --------- lib/pleroma/web/mastodon_api/mastodon_api.ex | 1 - test/notification_test.exs | 20 ++++++++----------- test/web/activity_pub/activity_pub_test.exs | 6 ++---- .../notification_controller_test.exs | 8 ++------ .../views/notification_view_test.exs | 2 +- 8 files changed, 16 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4168086e2..e3be2ea08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - **Breaking:** BBCode and Markdown formatters will no longer return any `\n` and only use `
` for newlines +### Removed +- **Breaking:** removed `with_move` parameter from notifications timeline. + ## [2.0.0] - 2019-03-08 ### Security - Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request. diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md index 476a4a2bf..b12d3092c 100644 --- a/docs/API/differences_in_mastoapi_responses.md +++ b/docs/API/differences_in_mastoapi_responses.md @@ -117,7 +117,6 @@ The `type` value is `pleroma:emoji_reaction`. Has these fields: Accepts additional parameters: - `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`. -- `with_move`: boolean, when set to `true` will include Move notifications. `false` by default. ## POST `/api/v1/statuses` diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 60dba3434..3ef3b3f58 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -77,7 +77,6 @@ def for_user_query(user, opts \\ %{}) do |> exclude_notification_muted(user, exclude_notification_muted_opts) |> exclude_blocked(user, exclude_blocked_opts) |> exclude_visibility(opts) - |> exclude_move(opts) end defp exclude_blocked(query, user, opts) do @@ -107,14 +106,6 @@ defp exclude_notification_muted(query, user, opts) do |> where([n, a, o, tm], is_nil(tm.user_id)) end - defp exclude_move(query, %{with_move: true}) do - query - end - - defp exclude_move(query, _opts) do - where(query, [n, a], fragment("?->>'type' != 'Move'", a.data)) - end - @valid_visibilities ~w[direct unlisted public private] defp exclude_visibility(query, %{exclude_visibilities: visibility}) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api.ex b/lib/pleroma/web/mastodon_api/mastodon_api.ex index 3fe2be521..a2dc9bc71 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api.ex @@ -72,7 +72,6 @@ defp cast_params(params) do exclude_visibilities: {:array, :string}, reblogs: :boolean, with_muted: :boolean, - with_move: :boolean, account_ap_id: :string } diff --git a/test/notification_test.exs b/test/notification_test.exs index 56a581810..d240ede94 100644 --- a/test/notification_test.exs +++ b/test/notification_test.exs @@ -667,7 +667,13 @@ test "move activity generates a notification" do Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user) ObanHelpers.perform_all() - assert [] = Notification.for_user(follower) + assert [ + %{ + activity: %{ + data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id} + } + } + ] = Notification.for_user(follower) assert [ %{ @@ -675,17 +681,7 @@ test "move activity generates a notification" do data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id} } } - ] = Notification.for_user(follower, %{with_move: true}) - - assert [] = Notification.for_user(other_follower) - - assert [ - %{ - activity: %{ - data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id} - } - } - ] = Notification.for_user(other_follower, %{with_move: true}) + ] = Notification.for_user(other_follower) end end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 3dd3dd04d..d86c8260e 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -1955,11 +1955,9 @@ test "create" do activity = %Activity{activity | object: nil} - assert [%Notification{activity: ^activity}] = - Notification.for_user(follower, %{with_move: true}) + assert [%Notification{activity: ^activity}] = Notification.for_user(follower) - assert [%Notification{activity: ^activity}] = - Notification.for_user(follower_move_opted_out, %{with_move: true}) + assert [%Notification{activity: ^activity}] = Notification.for_user(follower_move_opted_out) end test "old user must be in the new user's `also_known_as` list" do diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs index d452ddbdd..dbe9a7fd7 100644 --- a/test/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/web/mastodon_api/controllers/notification_controller_test.exs @@ -407,7 +407,7 @@ test "see notifications after muting user with notifications and with_muted para assert length(json_response(conn, 200)) == 1 end - test "see move notifications with `with_move` parameter" do + test "see move notifications" do old_user = insert(:user) new_user = insert(:user, also_known_as: [old_user.ap_id]) %{user: follower, conn: conn} = oauth_access(["read:notifications"]) @@ -416,11 +416,7 @@ test "see move notifications with `with_move` parameter" do Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user) Pleroma.Tests.ObanHelpers.perform_all() - ret_conn = get(conn, "/api/v1/notifications") - - assert json_response(ret_conn, 200) == [] - - conn = get(conn, "/api/v1/notifications", %{"with_move" => "true"}) + conn = get(conn, "/api/v1/notifications") assert length(json_response(conn, 200)) == 1 end diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs index 4df9c3c03..d04c3022f 100644 --- a/test/web/mastodon_api/views/notification_view_test.exs +++ b/test/web/mastodon_api/views/notification_view_test.exs @@ -120,7 +120,7 @@ test "Move notification" do old_user = refresh_record(old_user) new_user = refresh_record(new_user) - [notification] = Notification.for_user(follower, %{with_move: true}) + [notification] = Notification.for_user(follower) expected = %{ id: to_string(notification.id), From d198e7fa2a0c92be4e99c5a765de85096d318bfe Mon Sep 17 00:00:00 2001 From: eugenijm Date: Tue, 28 Jan 2020 09:47:59 +0300 Subject: [PATCH 06/17] Admin API: `PATCH /api/pleroma/admin/users/:nickname/change_password` --- CHANGELOG.md | 1 + docs/API/admin_api.md | 8 +++++ lib/pleroma/moderation_log.ex | 11 +++++++ .../web/admin_api/admin_api_controller.ex | 33 +++++++++++++++++++ lib/pleroma/web/router.ex | 1 + .../admin_api/admin_api_controller_test.exs | 26 +++++++++++++++ 6 files changed, 80 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4168086e2..0f8091c8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - 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. - Mastodon API: Limit timeline requests to 3 per timeline per 500ms per user/ip by default. +- Admin API: `PATCH /api/pleroma/admin/users/:nickname/change_password` ### Added diff --git a/docs/API/admin_api.md b/docs/API/admin_api.md index 47afdfba5..cb8201f11 100644 --- a/docs/API/admin_api.md +++ b/docs/API/admin_api.md @@ -414,6 +414,14 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret - `nicknames` - Response: none (code `204`) +## `PATCH /api/pleroma/admin/users/:nickname/change_password` + +### Change the user password + +- Params: + - `new_password` +- Response: none (code `200`) + ## `GET /api/pleroma/admin/reports` ### Get a list of reports diff --git a/lib/pleroma/moderation_log.ex b/lib/pleroma/moderation_log.ex index e32895f70..b5435a553 100644 --- a/lib/pleroma/moderation_log.ex +++ b/lib/pleroma/moderation_log.ex @@ -605,6 +605,17 @@ def get_log_entry_message(%ModerationLog{ }" end + @spec get_log_entry_message(ModerationLog) :: String.t() + def get_log_entry_message(%ModerationLog{ + data: %{ + "actor" => %{"nickname" => actor_nickname}, + "action" => "change_password", + "subject" => subjects + } + }) do + "@#{actor_nickname} changed password for users: #{users_to_nicknames_string(subjects)}" + end + defp nicknames_to_string(nicknames) do nicknames |> Enum.map(&"@#{&1}") diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 175260bc2..2aa2c6ac2 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -658,6 +658,39 @@ def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nic json_response(conn, :no_content, "") end + @doc "Changes password for a given user" + def change_password(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname} = params) do + with {_, user} <- {:user, User.get_cached_by_nickname(nickname)}, + {:ok, _user} <- + User.reset_password(user, %{ + password: params["new_password"], + password_confirmation: params["new_password"] + }) do + ModerationLog.insert_log(%{ + actor: admin, + subject: [user], + action: "change_password" + }) + + User.force_password_reset_async(user) + + ModerationLog.insert_log(%{ + actor: admin, + subject: [user], + action: "force_password_reset" + }) + + json(conn, %{status: "success"}) + else + {:error, changeset} -> + {_, {error, _}} = Enum.at(changeset.errors, 0) + json(conn, %{error: "New password #{error}."}) + + _ -> + json(conn, %{error: "Unable to change password."}) + end + end + def list_reports(conn, params) do {page, page_size} = page_params(params) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index e4e3ee704..c03ad101e 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -173,6 +173,7 @@ defmodule Pleroma.Web.Router do get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset) patch("/users/force_password_reset", AdminAPIController, :force_password_reset) + patch("/users/:nickname/change_password", AdminAPIController, :change_password) get("/users", AdminAPIController, :list_users) get("/users/:nickname", AdminAPIController, :user_show) diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index e4c152fb7..0c1214f05 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -3389,6 +3389,32 @@ test "returns log filtered by search", %{conn: conn, moderator: moderator} do end end + describe "PATCH /users/:nickname/change_password" do + test "changes password", %{conn: conn, admin: admin} do + user = insert(:user) + assert user.password_reset_pending == false + + conn = + patch(conn, "/api/pleroma/admin/users/#{user.nickname}/change_password", %{ + "new_password" => "password" + }) + + assert json_response(conn, 200) == %{"status" => "success"} + + ObanHelpers.perform_all() + + assert User.get_by_id(user.id).password_reset_pending == true + + [log_entry1, log_entry2] = ModerationLog |> Repo.all() |> Enum.sort() + + assert ModerationLog.get_log_entry_message(log_entry1) == + "@#{admin.nickname} changed password for users: @#{user.nickname}" + + assert ModerationLog.get_log_entry_message(log_entry2) == + "@#{admin.nickname} forced password reset for users: @#{user.nickname}" + end + end + describe "PATCH /users/:nickname/force_password_reset" do test "sets password_reset_pending to true", %{conn: conn} do user = insert(:user) From 13cce9c0debbf9a80ed5da26cb34ca563e5e1417 Mon Sep 17 00:00:00 2001 From: eugenijm Date: Fri, 31 Jan 2020 21:07:46 +0300 Subject: [PATCH 07/17] Admin API: `PATCH /api/pleroma/admin/users/:nickname/credentials`, `GET /api/pleroma/admin/users/:nickname/credentials`. --- CHANGELOG.md | 2 +- docs/API/admin_api.md | 75 +++++++++++++++- lib/pleroma/moderation_log.ex | 4 +- lib/pleroma/user.ex | 86 ++++++++++++++++++- .../web/admin_api/admin_api_controller.ex | 34 +++++--- .../web/admin_api/views/account_view.ex | 40 +++++++++ .../controllers/account_controller.ex | 60 +++---------- lib/pleroma/web/router.ex | 3 +- .../admin_api/admin_api_controller_test.exs | 57 ++++++++++-- 9 files changed, 286 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f8091c8c..ec04c26e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,7 +67,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - 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. - Mastodon API: Limit timeline requests to 3 per timeline per 500ms per user/ip by default. -- Admin API: `PATCH /api/pleroma/admin/users/:nickname/change_password` +- Admin API: `PATCH /api/pleroma/admin/users/:nickname/credentials` and `GET /api/pleroma/admin/users/:nickname/credentials` ### Added diff --git a/docs/API/admin_api.md b/docs/API/admin_api.md index cb8201f11..edcf73e14 100644 --- a/docs/API/admin_api.md +++ b/docs/API/admin_api.md @@ -414,12 +414,81 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret - `nicknames` - Response: none (code `204`) -## `PATCH /api/pleroma/admin/users/:nickname/change_password` +## `GET /api/pleroma/admin/users/:nickname/credentials` -### Change the user password +### Get the user's email, password, display and settings-related fields - Params: - - `new_password` + - `nickname` + +- Response: + +```json +{ + "actor_type": "Person", + "allow_following_move": true, + "avatar": "https://pleroma.social/media/7e8e7508fd545ef580549b6881d80ec0ff2c81ed9ad37b9bdbbdf0e0d030159d.jpg", + "background": "https://pleroma.social/media/4de34c0bd10970d02cbdef8972bef0ebbf55f43cadc449554d4396156162fe9a.jpg", + "banner": "https://pleroma.social/media/8d92ba2bd244b613520abf557dd448adcd30f5587022813ee9dd068945986946.jpg", + "bio": "bio", + "default_scope": "public", + "discoverable": false, + "email": "user@example.com", + "fields": [ + { + "name": "example", + "value": "https://example.com" + } + ], + "hide_favorites": false, + "hide_followers": false, + "hide_followers_count": false, + "hide_follows": false, + "hide_follows_count": false, + "id": "9oouHaEEUR54hls968", + "locked": true, + "name": "user", + "no_rich_text": true, + "pleroma_settings_store": {}, + "raw_fields": [ + { + "id": 1, + "name": "example", + "value": "https://example.com" + }, + ], + "show_role": true, + "skip_thread_containment": false +} +``` + +## `PATCH /api/pleroma/admin/users/:nickname/credentials` + +### Change the user's email, password, display and settings-related fields + +- Params: + - `email` + - `password` + - `name` + - `bio` + - `avatar` + - `locked` + - `no_rich_text` + - `default_scope` + - `banner` + - `hide_follows` + - `hide_followers` + - `hide_followers_count` + - `hide_follows_count` + - `hide_favorites` + - `allow_following_move` + - `background` + - `show_role` + - `skip_thread_containment` + - `fields` + - `discoverable` + - `actor_type` + - Response: none (code `200`) ## `GET /api/pleroma/admin/reports` diff --git a/lib/pleroma/moderation_log.ex b/lib/pleroma/moderation_log.ex index b5435a553..7aacd9d80 100644 --- a/lib/pleroma/moderation_log.ex +++ b/lib/pleroma/moderation_log.ex @@ -609,11 +609,11 @@ def get_log_entry_message(%ModerationLog{ def get_log_entry_message(%ModerationLog{ data: %{ "actor" => %{"nickname" => actor_nickname}, - "action" => "change_password", + "action" => "updated_users", "subject" => subjects } }) do - "@#{actor_nickname} changed password for users: #{users_to_nicknames_string(subjects)}" + "@#{actor_nickname} updated 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 911dde6e2..44de64345 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -417,9 +417,55 @@ def update_changeset(struct, params \\ %{}) do |> validate_format(:nickname, local_nickname_regex()) |> validate_length(:bio, max: bio_limit) |> validate_length(:name, min: 1, max: name_limit) + |> put_fields() + |> put_change_if_present(:bio, &{:ok, parse_bio(&1, struct)}) + |> put_change_if_present(:avatar, &put_upload(&1, :avatar)) + |> put_change_if_present(:banner, &put_upload(&1, :banner)) + |> put_change_if_present(:background, &put_upload(&1, :background)) + |> put_change_if_present( + :pleroma_settings_store, + &{:ok, Map.merge(struct.pleroma_settings_store, &1)} + ) |> validate_fields(false) end + defp put_fields(changeset) do + if raw_fields = get_change(changeset, :raw_fields) do + raw_fields = + raw_fields + |> Enum.filter(fn %{"name" => n} -> n != "" end) + + fields = + raw_fields + |> Enum.map(fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end) + + changeset + |> put_change(:raw_fields, raw_fields) + |> put_change(:fields, fields) + else + changeset + end + end + + defp put_change_if_present(changeset, map_field, value_function) do + if value = get_change(changeset, map_field) do + with {:ok, new_value} <- value_function.(value) do + put_change(changeset, map_field, new_value) + else + _ -> changeset + end + else + changeset + end + end + + defp put_upload(value, type) do + with %Plug.Upload{} <- value, + {:ok, object} <- ActivityPub.upload(value, type: type) do + {:ok, object.data} + end + end + def upgrade_changeset(struct, params \\ %{}, remote? \\ false) do bio_limit = Pleroma.Config.get([:instance, :user_bio_length], 5000) name_limit = Pleroma.Config.get([:instance, :user_name_length], 100) @@ -463,6 +509,27 @@ def upgrade_changeset(struct, params \\ %{}, remote? \\ false) do |> validate_fields(remote?) end + def update_as_admin_changeset(struct, params) do + struct + |> update_changeset(params) + |> cast(params, [:email]) + |> delete_change(:also_known_as) + |> unique_constraint(:email) + |> validate_format(:email, @email_regex) + end + + @spec update_as_admin(%User{}, map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()} + def update_as_admin(user, params) do + params = Map.put(params, "password_confirmation", params["password"]) + changeset = update_as_admin_changeset(user, params) + + if params["password"] do + reset_password(user, changeset, params) + else + User.update_and_set_cache(changeset) + end + end + def password_update_changeset(struct, params) do struct |> cast(params, [:password, :password_confirmation]) @@ -473,10 +540,14 @@ def password_update_changeset(struct, params) do end @spec reset_password(User.t(), map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()} - def reset_password(%User{id: user_id} = user, data) do + def reset_password(%User{} = user, params) do + reset_password(user, user, params) + end + + def reset_password(%User{id: user_id} = user, struct, params) do multi = Multi.new() - |> Multi.update(:user, password_update_changeset(user, data)) + |> Multi.update(:user, password_update_changeset(struct, params)) |> Multi.delete_all(:tokens, OAuth.Token.Query.get_by_user(user_id)) |> Multi.delete_all(:auth, OAuth.Authorization.delete_by_user_query(user)) @@ -1856,6 +1927,17 @@ def fields(%{fields: nil}), do: [] def fields(%{fields: fields}), do: fields + def sanitized_fields(%User{} = user) do + user + |> User.fields() + |> Enum.map(fn %{"name" => name, "value" => value} -> + %{ + "name" => name, + "value" => Pleroma.HTML.filter_tags(value, Pleroma.HTML.Scrubber.LinksOnly) + } + end) + end + def validate_fields(changeset, remote? \\ false) do limit_name = if remote?, do: :max_remote_account_fields, else: :max_account_fields limit = Pleroma.Config.get([:instance, limit_name], 0) diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index 2aa2c6ac2..0368df1e9 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -38,7 +38,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do plug( OAuthScopesPlug, %{scopes: ["read:accounts"], admin: true} - when action in [:list_users, :user_show, :right_get] + when action in [:list_users, :user_show, :right_get, :show_user_credentials] ) plug( @@ -54,7 +54,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do :tag_users, :untag_users, :right_add, - :right_delete + :right_delete, + :update_user_credentials ] ) @@ -658,21 +659,34 @@ def force_password_reset(%{assigns: %{user: admin}} = conn, %{"nicknames" => nic json_response(conn, :no_content, "") end - @doc "Changes password for a given user" - def change_password(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname} = params) do + @doc "Show a given user's credentials" + def show_user_credentials(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do + with %User{} = user <- User.get_cached_by_nickname_or_id(nickname) do + conn + |> put_view(AccountView) + |> render("credentials.json", %{user: user, for: admin}) + else + _ -> {:error, :not_found} + end + end + + @doc "Updates a given user" + def update_user_credentials( + %{assigns: %{user: admin}} = conn, + %{"nickname" => nickname} = params + ) do with {_, user} <- {:user, User.get_cached_by_nickname(nickname)}, {:ok, _user} <- - User.reset_password(user, %{ - password: params["new_password"], - password_confirmation: params["new_password"] - }) do + User.update_as_admin(user, params) do ModerationLog.insert_log(%{ actor: admin, subject: [user], - action: "change_password" + action: "updated_users" }) - User.force_password_reset_async(user) + if params["password"] do + User.force_password_reset_async(user) + end ModerationLog.insert_log(%{ actor: admin, diff --git a/lib/pleroma/web/admin_api/views/account_view.ex b/lib/pleroma/web/admin_api/views/account_view.ex index 1e03849de..a16a3ebf0 100644 --- a/lib/pleroma/web/admin_api/views/account_view.ex +++ b/lib/pleroma/web/admin_api/views/account_view.ex @@ -23,6 +23,43 @@ def render("index.json", %{users: users}) do } end + def render("credentials.json", %{user: user, for: for_user}) do + user = User.sanitize_html(user, User.html_filter_policy(for_user)) + avatar = User.avatar_url(user) |> MediaProxy.url() + banner = User.banner_url(user) |> MediaProxy.url() + background = image_url(user.background) |> MediaProxy.url() + + user + |> Map.take([ + :id, + :bio, + :email, + :fields, + :name, + :nickname, + :locked, + :no_rich_text, + :default_scope, + :hide_follows, + :hide_followers_count, + :hide_follows_count, + :hide_followers, + :hide_favorites, + :allow_following_move, + :show_role, + :skip_thread_containment, + :pleroma_settings_store, + :raw_fields, + :discoverable, + :actor_type + ]) + |> Map.merge(%{ + "avatar" => avatar, + "banner" => banner, + "background" => background + }) + end + def render("show.json", %{user: user}) do avatar = User.avatar_url(user) |> MediaProxy.url() display_name = Pleroma.HTML.strip_tags(user.name || user.nickname) @@ -104,4 +141,7 @@ defp parse_error(errors) do "" end end + + defp image_url(%{"url" => [%{"href" => href} | _]}), do: href + defp image_url(_), do: nil end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 88c997b9f..56e6214c5 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -8,7 +8,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, truthy_param?: 1, assign_account_by_id: 2, json_response: 3] - alias Pleroma.Emoji alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.RateLimiter alias Pleroma.User @@ -140,17 +139,6 @@ def verify_credentials(%{assigns: %{user: user}} = conn, _) do def update_credentials(%{assigns: %{user: original_user}} = conn, params) do user = original_user - params = - if Map.has_key?(params, "fields_attributes") do - Map.update!(params, "fields_attributes", fn fields -> - fields - |> normalize_fields_attributes() - |> Enum.filter(fn %{"name" => n} -> n != "" end) - end) - else - params - end - user_params = [ :no_rich_text, @@ -169,46 +157,20 @@ def update_credentials(%{assigns: %{user: original_user}} = conn, params) do add_if_present(acc, params, to_string(key), key, &{:ok, truthy_param?(&1)}) end) |> add_if_present(params, "display_name", :name) - |> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value, user)} end) - |> add_if_present(params, "avatar", :avatar, fn value -> - with %Plug.Upload{} <- value, - {:ok, object} <- ActivityPub.upload(value, type: :avatar) do - {:ok, object.data} - end - end) - |> add_if_present(params, "header", :banner, fn value -> - with %Plug.Upload{} <- value, - {:ok, object} <- ActivityPub.upload(value, type: :banner) do - {:ok, object.data} - end - end) - |> add_if_present(params, "pleroma_background_image", :background, fn value -> - with %Plug.Upload{} <- value, - {:ok, object} <- ActivityPub.upload(value, type: :background) do - {:ok, object.data} - end - end) - |> add_if_present(params, "fields_attributes", :fields, fn fields -> - fields = Enum.map(fields, fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end) - - {:ok, fields} - end) - |> add_if_present(params, "fields_attributes", :raw_fields) - |> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value -> - {:ok, Map.merge(user.pleroma_settings_store, value)} - end) + |> add_if_present(params, "note", :bio) + |> add_if_present(params, "avatar", :avatar) + |> add_if_present(params, "header", :banner) + |> add_if_present(params, "pleroma_background_image", :background) + |> add_if_present( + params, + "fields_attributes", + :raw_fields, + &{:ok, normalize_fields_attributes(&1)} + ) + |> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store) |> add_if_present(params, "default_scope", :default_scope) |> add_if_present(params, "actor_type", :actor_type) - emojis_text = (user_params["display_name"] || "") <> (user_params["note"] || "") - - user_emojis = - user - |> Map.get(:emoji, []) - |> Enum.concat(Emoji.Formatter.get_emoji_map(emojis_text)) - |> Enum.dedup() - - user_params = Map.put(user_params, :emoji, user_emojis) changeset = User.update_changeset(user, user_params) with {:ok, user} <- User.update_and_set_cache(changeset) do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index c03ad101e..2927775eb 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -173,7 +173,8 @@ defmodule Pleroma.Web.Router do get("/users/:nickname/password_reset", AdminAPIController, :get_password_reset) patch("/users/force_password_reset", AdminAPIController, :force_password_reset) - patch("/users/:nickname/change_password", AdminAPIController, :change_password) + get("/users/:nickname/credentials", AdminAPIController, :show_user_credentials) + patch("/users/:nickname/credentials", AdminAPIController, :update_user_credentials) get("/users", AdminAPIController, :list_users) get("/users/:nickname", AdminAPIController, :user_show) diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 0c1214f05..0a317cf88 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -3389,30 +3389,73 @@ test "returns log filtered by search", %{conn: conn, moderator: moderator} do end end - describe "PATCH /users/:nickname/change_password" do - test "changes password", %{conn: conn, admin: admin} do + describe "GET /users/:nickname/credentials" do + test "gets the user credentials", %{conn: conn} do + user = insert(:user) + conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials") + + response = assert json_response(conn, 200) + assert response["email"] == user.email + end + + test "returns 403 if requested by a non-admin" do + user = insert(:user) + + conn = + build_conn() + |> assign(:user, user) + |> get("/api/pleroma/admin/users/#{user.nickname}/credentials") + + assert json_response(conn, :forbidden) + end + end + + describe "PATCH /users/:nickname/credentials" do + test "changes password and email", %{conn: conn, admin: admin} do user = insert(:user) assert user.password_reset_pending == false conn = - patch(conn, "/api/pleroma/admin/users/#{user.nickname}/change_password", %{ - "new_password" => "password" + patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{ + "password" => "new_password", + "email" => "new_email@example.com", + "name" => "new_name" }) assert json_response(conn, 200) == %{"status" => "success"} ObanHelpers.perform_all() - assert User.get_by_id(user.id).password_reset_pending == true + updated_user = User.get_by_id(user.id) - [log_entry1, log_entry2] = ModerationLog |> Repo.all() |> Enum.sort() + assert updated_user.email == "new_email@example.com" + assert updated_user.name == "new_name" + assert updated_user.password_hash != user.password_hash + assert updated_user.password_reset_pending == true + + [log_entry2, log_entry1] = ModerationLog |> Repo.all() |> Enum.sort() assert ModerationLog.get_log_entry_message(log_entry1) == - "@#{admin.nickname} changed password for users: @#{user.nickname}" + "@#{admin.nickname} updated users: @#{user.nickname}" assert ModerationLog.get_log_entry_message(log_entry2) == "@#{admin.nickname} forced password reset for users: @#{user.nickname}" end + + test "returns 403 if requested by a non-admin" do + user = insert(:user) + + conn = + build_conn() + |> assign(:user, user) + |> patch("/api/pleroma/admin/users/#{user.nickname}/credentials", %{ + "password" => "new_password", + "email" => "new_email@example.com", + "name" => "new_name" + }) + + assert json_response(conn, :forbidden) + end end describe "PATCH /users/:nickname/force_password_reset" do From 4705590f76f6a875aa99f32c8b08c20d793470a8 Mon Sep 17 00:00:00 2001 From: Cevado Date: Mon, 16 Mar 2020 22:02:01 -0300 Subject: [PATCH 08/17] Fix ssl option on Ecto config breaking release To use `:ssl` option on Ecto config it's required to include Erlang ssl application, this prevents releases to start when `:ssl` option is set to true. --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index dd598345c..890979f8b 100644 --- a/mix.exs +++ b/mix.exs @@ -63,7 +63,7 @@ def copy_nginx_config(%{path: target_path} = release) do def application do [ mod: {Pleroma.Application, []}, - extra_applications: [:logger, :runtime_tools, :comeonin, :quack, :fast_sanitize], + extra_applications: [:logger, :runtime_tools, :comeonin, :quack, :fast_sanitize, :ssl], included_applications: [:ex_syslogger] ] end From ec3719f5391d6f9945cec2e36287049d72743cd4 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Wed, 18 Mar 2020 20:30:31 +0300 Subject: [PATCH 09/17] Improved in-test config management functions. --- test/config/transfer_task_test.exs | 4 +-- test/conversation_test.exs | 4 +-- test/plugs/instance_static_test.exs | 4 +-- test/plugs/user_is_admin_plug_test.exs | 8 ++--- test/support/helpers.ex | 30 ++++++++++++++++++- test/tasks/config_test.exs | 4 +-- test/upload_test.exs | 4 +-- test/uploaders/s3_test.exs | 10 +++---- test/user_test.exs | 4 +-- .../activity_pub_controller_test.exs | 4 +-- .../mrf/object_age_policy_test.exs | 10 +++---- .../activity_pub/mrf/simple_policy_test.exs | 22 +++++++------- test/web/activity_pub/publisher_test.exs | 4 +-- test/web/activity_pub/transmogrifier_test.exs | 12 ++------ .../activity_pub/views/object_view_test.exs | 4 +-- .../admin_api/admin_api_controller_test.exs | 29 +++++------------- test/web/federator_test.exs | 4 +-- test/web/feed/user_controller_test.exs | 4 +-- test/web/instances/instance_test.exs | 4 +-- test/web/instances/instances_test.exs | 4 +-- .../controllers/account_controller_test.exs | 4 +-- .../controllers/status_controller_test.exs | 4 +-- test/web/oauth/ldap_authorization_test.exs | 8 ++--- test/web/oauth/oauth_controller_test.exs | 7 +---- test/web/ostatus/ostatus_controller_test.exs | 4 +-- .../controllers/account_controller_test.exs | 4 +-- .../controllers/emoji_api_controller_test.exs | 4 +-- .../static_fe/static_fe_controller_test.exs | 8 ++--- .../remote_follow_controller_test.exs | 4 +-- test/web/twitter_api/twitter_api_test.exs | 16 +++------- test/web/twitter_api/util_controller_test.exs | 4 +-- .../web_finger/web_finger_controller_test.exs | 4 +-- 32 files changed, 89 insertions(+), 155 deletions(-) diff --git a/test/config/transfer_task_test.exs b/test/config/transfer_task_test.exs index 01d04761d..7bfae67bf 100644 --- a/test/config/transfer_task_test.exs +++ b/test/config/transfer_task_test.exs @@ -10,9 +10,7 @@ defmodule Pleroma.Config.TransferTaskTest do alias Pleroma.Config.TransferTask alias Pleroma.ConfigDB - clear_config(:configurable_from_database) do - Pleroma.Config.put(:configurable_from_database, true) - end + clear_config(:configurable_from_database, true) test "transfer config values from db to env" do refute Application.get_env(:pleroma, :test_key) diff --git a/test/conversation_test.exs b/test/conversation_test.exs index dc0027d04..3c54253e3 100644 --- a/test/conversation_test.exs +++ b/test/conversation_test.exs @@ -11,9 +11,7 @@ defmodule Pleroma.ConversationTest do import Pleroma.Factory - clear_config_all([:instance, :federating]) do - Pleroma.Config.put([:instance, :federating], true) - end + clear_config_all([:instance, :federating], true) test "it goes through old direct conversations" do user = insert(:user) diff --git a/test/plugs/instance_static_test.exs b/test/plugs/instance_static_test.exs index 8cd9b5712..2e9d2dc46 100644 --- a/test/plugs/instance_static_test.exs +++ b/test/plugs/instance_static_test.exs @@ -12,9 +12,7 @@ defmodule Pleroma.Web.RuntimeStaticPlugTest do on_exit(fn -> File.rm_rf(@dir) end) end - clear_config([:instance, :static_dir]) do - Pleroma.Config.put([:instance, :static_dir], @dir) - end + clear_config([:instance, :static_dir], @dir) test "overrides index" do bundled_index = get(build_conn(), "/") diff --git a/test/plugs/user_is_admin_plug_test.exs b/test/plugs/user_is_admin_plug_test.exs index 015d51018..1062d6e70 100644 --- a/test/plugs/user_is_admin_plug_test.exs +++ b/test/plugs/user_is_admin_plug_test.exs @@ -9,9 +9,7 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do import Pleroma.Factory describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage]) do - Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false) - end + clear_config([:auth, :enforce_oauth_admin_scope_usage], false) test "accepts a user that is an admin" do user = insert(:user, is_admin: true) @@ -42,9 +40,7 @@ test "denies when a user isn't set" do end describe "with [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage]) do - Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true) - end + clear_config([:auth, :enforce_oauth_admin_scope_usage], true) setup do admin_user = insert(:user, is_admin: true) diff --git a/test/support/helpers.ex b/test/support/helpers.ex index 6bf4b019e..c6f7fa5e2 100644 --- a/test/support/helpers.ex +++ b/test/support/helpers.ex @@ -26,6 +26,25 @@ defmacro clear_config(config_path, do: yield) do end end + defmacro clear_config(config_path, temp_setting) do + quote do + clear_config(unquote(config_path)) do + Config.put(unquote(config_path), unquote(temp_setting)) + end + end + end + + @doc """ + From _within a test case_, sets config to provided value and restores initial value on exit. + For multi-case setup use `clear_config/2` instead. + """ + def set_config(config_path, temp_setting) do + initial_setting = Config.get(config_path) + Config.put(config_path, temp_setting) + + ExUnit.Callbacks.on_exit(fn -> Config.put(config_path, initial_setting) end) + end + @doc "Stores initial config value and restores it after *all* test examples are executed." defmacro clear_config_all(config_path) do quote do @@ -50,6 +69,14 @@ defmacro clear_config_all(config_path, do: yield) do end end + defmacro clear_config_all(config_path, temp_setting) do + quote do + clear_config_all(unquote(config_path)) do + Config.put(unquote(config_path), unquote(temp_setting)) + end + end + end + defmacro __using__(_opts) do quote do import Pleroma.Tests.Helpers, @@ -57,7 +84,8 @@ defmacro __using__(_opts) do clear_config: 1, clear_config: 2, clear_config_all: 1, - clear_config_all: 2 + clear_config_all: 2, + set_config: 2 ] def to_datetime(naive_datetime) do diff --git a/test/tasks/config_test.exs b/test/tasks/config_test.exs index a6c0de351..b0c2efc98 100644 --- a/test/tasks/config_test.exs +++ b/test/tasks/config_test.exs @@ -20,9 +20,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do :ok end - clear_config_all(:configurable_from_database) do - Pleroma.Config.put(:configurable_from_database, true) - end + clear_config_all(:configurable_from_database, true) test "error if file with custom settings doesn't exist" do Mix.Tasks.Pleroma.Config.migrate_to_db("config/not_existance_config_file.exs") diff --git a/test/upload_test.exs b/test/upload_test.exs index 6ce42b630..6bf7f2417 100644 --- a/test/upload_test.exs +++ b/test/upload_test.exs @@ -250,9 +250,7 @@ test "escapes reserved uri characters" do end describe "Setting a custom base_url for uploaded media" do - clear_config([Pleroma.Upload, :base_url]) do - Pleroma.Config.put([Pleroma.Upload, :base_url], "https://cache.pleroma.social") - end + clear_config([Pleroma.Upload, :base_url], "https://cache.pleroma.social") test "returns a media url with configured base_url" do base_url = Pleroma.Config.get([Pleroma.Upload, :base_url]) diff --git a/test/uploaders/s3_test.exs b/test/uploaders/s3_test.exs index fdc7eff41..96c21c0e5 100644 --- a/test/uploaders/s3_test.exs +++ b/test/uploaders/s3_test.exs @@ -11,12 +11,10 @@ defmodule Pleroma.Uploaders.S3Test do import Mock import ExUnit.CaptureLog - clear_config([Pleroma.Uploaders.S3]) do - Config.put([Pleroma.Uploaders.S3], - bucket: "test_bucket", - public_endpoint: "https://s3.amazonaws.com" - ) - end + clear_config(Pleroma.Uploaders.S3, + bucket: "test_bucket", + public_endpoint: "https://s3.amazonaws.com" + ) describe "get_file/1" do test "it returns path to local folder for files" do diff --git a/test/user_test.exs b/test/user_test.exs index b07fed42b..e0e7a26b8 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -476,9 +476,7 @@ test "it sets the password_hash and ap_id" do email: "email@example.com" } - clear_config([:instance, :account_activation_required]) do - Pleroma.Config.put([:instance, :account_activation_required], true) - end + clear_config([:instance, :account_activation_required], true) test "it creates unconfirmed user" do changeset = User.register_changeset(%User{}, @full_user_data) diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index bd8e0b5cc..df0c53458 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -26,9 +26,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do :ok end - clear_config([:instance, :federating]) do - Config.put([:instance, :federating], true) - end + clear_config([:instance, :federating], true) describe "/relay" do clear_config([:instance, :allow_relay]) diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs index 643609da4..bdbbb1fc4 100644 --- a/test/web/activity_pub/mrf/object_age_policy_test.exs +++ b/test/web/activity_pub/mrf/object_age_policy_test.exs @@ -9,12 +9,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy alias Pleroma.Web.ActivityPub.Visibility - clear_config([:mrf_object_age]) do - Config.put(:mrf_object_age, - threshold: 172_800, - actions: [:delist, :strip_followers] - ) - end + clear_config(:mrf_object_age, + threshold: 172_800, + actions: [:delist, :strip_followers] + ) setup_all do Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs index df0f223f8..97aec6622 100644 --- a/test/web/activity_pub/mrf/simple_policy_test.exs +++ b/test/web/activity_pub/mrf/simple_policy_test.exs @@ -8,18 +8,16 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do alias Pleroma.Config alias Pleroma.Web.ActivityPub.MRF.SimplePolicy - clear_config([:mrf_simple]) do - Config.put(:mrf_simple, - media_removal: [], - media_nsfw: [], - federated_timeline_removal: [], - report_removal: [], - reject: [], - accept: [], - avatar_removal: [], - banner_removal: [] - ) - end + clear_config(:mrf_simple, + media_removal: [], + media_nsfw: [], + federated_timeline_removal: [], + report_removal: [], + reject: [], + accept: [], + avatar_removal: [], + banner_removal: [] + ) describe "when :media_removal" do test "is empty" do diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs index da26b13f7..ed9c951dd 100644 --- a/test/web/activity_pub/publisher_test.exs +++ b/test/web/activity_pub/publisher_test.exs @@ -23,9 +23,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do :ok end - clear_config_all([:instance, :federating]) do - Pleroma.Config.put([:instance, :federating], true) - end + clear_config_all([:instance, :federating], true) describe "gather_webfinger_links/1" do test "it returns links" do diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index efbca82f6..c025b6b78 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -1351,9 +1351,7 @@ test "it accepts Move activities" do end describe "`handle_incoming/2`, Mastodon format `replies` handling" do - clear_config([:activitypub, :note_replies_output_limit]) do - Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5) - end + clear_config([:activitypub, :note_replies_output_limit], 5) clear_config([:instance, :federation_incoming_replies_max_depth]) @@ -1394,9 +1392,7 @@ test "does NOT schedule background fetching of `replies` beyond max thread depth end describe "`handle_incoming/2`, Pleroma format `replies` handling" do - clear_config([:activitypub, :note_replies_output_limit]) do - Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5) - end + clear_config([:activitypub, :note_replies_output_limit], 5) clear_config([:instance, :federation_incoming_replies_max_depth]) @@ -2145,9 +2141,7 @@ test "returns object with emoji when object contains map tag" do end describe "set_replies/1" do - clear_config([:activitypub, :note_replies_output_limit]) do - Pleroma.Config.put([:activitypub, :note_replies_output_limit], 2) - end + clear_config([:activitypub, :note_replies_output_limit], 2) test "returns unmodified object if activity doesn't have self-replies" do data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) diff --git a/test/web/activity_pub/views/object_view_test.exs b/test/web/activity_pub/views/object_view_test.exs index 09866e99b..7dda20ec3 100644 --- a/test/web/activity_pub/views/object_view_test.exs +++ b/test/web/activity_pub/views/object_view_test.exs @@ -37,9 +37,7 @@ test "renders a note activity" do end describe "note activity's `replies` collection rendering" do - clear_config([:activitypub, :note_replies_output_limit]) do - Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5) - end + clear_config([:activitypub, :note_replies_output_limit], 5) test "renders `replies` collection for a note activity" do user = insert(:user) diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index e4c152fb7..5f3064941 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -43,9 +43,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "with [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage]) do - Config.put([:auth, :enforce_oauth_admin_scope_usage], true) - end + clear_config([:auth, :enforce_oauth_admin_scope_usage], true) test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope", %{admin: admin} do @@ -93,9 +91,7 @@ test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or bro end describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage]) do - Config.put([:auth, :enforce_oauth_admin_scope_usage], false) - end + clear_config([:auth, :enforce_oauth_admin_scope_usage], false) test "GET /api/pleroma/admin/users/:nickname requires " <> "read:accounts or admin:read:accounts or broader scope", @@ -581,13 +577,8 @@ test "/:right DELETE, can remove from a permission group (multiple)", %{ end describe "POST /api/pleroma/admin/email_invite, with valid config" do - clear_config([:instance, :registrations_open]) do - Config.put([:instance, :registrations_open], false) - end - - clear_config([:instance, :invites_enabled]) do - Config.put([:instance, :invites_enabled], true) - end + clear_config([:instance, :registrations_open], false) + clear_config([:instance, :invites_enabled], true) test "sends invitation and returns 204", %{admin: admin, conn: conn} do recipient_email = "foo@bar.com" @@ -1888,9 +1879,7 @@ test "returns 404 when the status does not exist", %{conn: conn} do end describe "GET /api/pleroma/admin/config" do - clear_config(:configurable_from_database) do - Config.put(:configurable_from_database, true) - end + clear_config(:configurable_from_database, true) test "when configuration from database is off", %{conn: conn} do Config.put(:configurable_from_database, false) @@ -2041,9 +2030,7 @@ test "POST /api/pleroma/admin/config error", %{conn: conn} do end) end - clear_config(:configurable_from_database) do - Config.put(:configurable_from_database, true) - end + clear_config(:configurable_from_database, true) @tag capture_log: true test "create new config setting in db", %{conn: conn} do @@ -3052,9 +3039,7 @@ test "proxy tuple ip", %{conn: conn} do end describe "GET /api/pleroma/admin/restart" do - clear_config(:configurable_from_database) do - Config.put(:configurable_from_database, true) - end + clear_config(:configurable_from_database, true) test "pleroma restarts", %{conn: conn} do capture_log(fn -> diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs index d2ee2267c..2b321d263 100644 --- a/test/web/federator_test.exs +++ b/test/web/federator_test.exs @@ -21,9 +21,7 @@ defmodule Pleroma.Web.FederatorTest do :ok end - clear_config_all([:instance, :federating]) do - Pleroma.Config.put([:instance, :federating], true) - end + clear_config_all([:instance, :federating], true) clear_config([:instance, :allow_relay]) clear_config([:instance, :rewrite_policy]) diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs index 00c50f003..49cfecde3 100644 --- a/test/web/feed/user_controller_test.exs +++ b/test/web/feed/user_controller_test.exs @@ -12,9 +12,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do alias Pleroma.Object alias Pleroma.User - clear_config([:instance, :federating]) do - Config.put([:instance, :federating], true) - end + clear_config([:instance, :federating], true) describe "feed" do clear_config([:feed]) diff --git a/test/web/instances/instance_test.exs b/test/web/instances/instance_test.exs index a3c93b986..ab8e5643b 100644 --- a/test/web/instances/instance_test.exs +++ b/test/web/instances/instance_test.exs @@ -10,9 +10,7 @@ defmodule Pleroma.Instances.InstanceTest do import Pleroma.Factory - clear_config_all([:instance, :federation_reachability_timeout_days]) do - Pleroma.Config.put([:instance, :federation_reachability_timeout_days], 1) - end + clear_config_all([:instance, :federation_reachability_timeout_days], 1) describe "set_reachable/1" do test "clears `unreachable_since` of existing matching Instance record having non-nil `unreachable_since`" do diff --git a/test/web/instances/instances_test.exs b/test/web/instances/instances_test.exs index c5d6abc9c..1d83c1a1c 100644 --- a/test/web/instances/instances_test.exs +++ b/test/web/instances/instances_test.exs @@ -7,9 +7,7 @@ defmodule Pleroma.InstancesTest do use Pleroma.DataCase - clear_config_all([:instance, :federation_reachability_timeout_days]) do - Pleroma.Config.put([:instance, :federation_reachability_timeout_days], 1) - end + clear_config_all([:instance, :federation_reachability_timeout_days], 1) describe "reachable?/1" do test "returns `true` for host / url with unknown reachability status" do diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index 7efccd9c4..5a78f2968 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -756,9 +756,7 @@ test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_ end describe "create account by app / rate limit" do - clear_config([:rate_limit, :app_account_creation]) do - Pleroma.Config.put([:rate_limit, :app_account_creation], {10_000, 2}) - end + clear_config([:rate_limit, :app_account_creation], {10_000, 2}) test "respects rate limit setting", %{conn: conn} do app_token = insert(:oauth_token, user: nil) diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs index fbf63f608..5259abdcd 100644 --- a/test/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/web/mastodon_api/controllers/status_controller_test.exs @@ -739,9 +739,7 @@ test "returns 404 error for a wrong id", %{conn: conn} do %{activity: activity} end - clear_config([:instance, :max_pinned_statuses]) do - Config.put([:instance, :max_pinned_statuses], 1) - end + clear_config([:instance, :max_pinned_statuses], 1) test "pin status", %{conn: conn, user: user, activity: activity} do id_str = to_string(activity.id) diff --git a/test/web/oauth/ldap_authorization_test.exs b/test/web/oauth/ldap_authorization_test.exs index c55b0ffc5..b348281c5 100644 --- a/test/web/oauth/ldap_authorization_test.exs +++ b/test/web/oauth/ldap_authorization_test.exs @@ -12,13 +12,9 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do @skip if !Code.ensure_loaded?(:eldap), do: :skip - clear_config_all([:ldap, :enabled]) do - Pleroma.Config.put([:ldap, :enabled], true) - end + clear_config_all([:ldap, :enabled], true) - clear_config_all(Pleroma.Web.Auth.Authenticator) do - Pleroma.Config.put(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.LDAPAuthenticator) - end + clear_config_all(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.LDAPAuthenticator) @tag @skip test "authorizes the existing user using LDAP credentials" do diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs index cff469c28..592612ddf 100644 --- a/test/web/oauth/oauth_controller_test.exs +++ b/test/web/oauth/oauth_controller_test.exs @@ -31,12 +31,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do ] end - clear_config([:auth, :oauth_consumer_strategies]) do - Pleroma.Config.put( - [:auth, :oauth_consumer_strategies], - ~w(twitter facebook) - ) - end + clear_config([:auth, :oauth_consumer_strategies], ~w(twitter facebook)) test "GET /oauth/authorize renders auth forms, including OAuth consumer form", %{ app: app, diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 3b84358e4..6a3dcf2cd 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -17,9 +17,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do :ok end - clear_config([:instance, :federating]) do - Config.put([:instance, :federating], true) - end + clear_config([:instance, :federating], true) # Note: see ActivityPubControllerTest for JSON format tests describe "GET /objects/:uuid (text/html)" do diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/web/pleroma_api/controllers/account_controller_test.exs index 245cc1579..bc359707d 100644 --- a/test/web/pleroma_api/controllers/account_controller_test.exs +++ b/test/web/pleroma_api/controllers/account_controller_test.exs @@ -27,9 +27,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do [user: user] end - clear_config([:instance, :account_activation_required]) do - Config.put([:instance, :account_activation_required], true) - end + clear_config([:instance, :account_activation_required], true) test "resend account confirmation email", %{conn: conn, user: user} do conn diff --git a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs index 4b9f5cf9a..146f3f4fe 100644 --- a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs @@ -13,9 +13,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do "emoji" ) - clear_config([:auth, :enforce_oauth_admin_scope_usage]) do - Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false) - end + clear_config([:auth, :enforce_oauth_admin_scope_usage], false) test "shared & non-shared pack information in list_packs is ok" do conn = build_conn() diff --git a/test/web/static_fe/static_fe_controller_test.exs b/test/web/static_fe/static_fe_controller_test.exs index c3d2ae3b4..aabbedb17 100644 --- a/test/web/static_fe/static_fe_controller_test.exs +++ b/test/web/static_fe/static_fe_controller_test.exs @@ -8,13 +8,9 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do import Pleroma.Factory - clear_config_all([:static_fe, :enabled]) do - Config.put([:static_fe, :enabled], true) - end + clear_config_all([:static_fe, :enabled], true) - clear_config([:instance, :federating]) do - Config.put([:instance, :federating], true) - end + clear_config([:instance, :federating], true) setup %{conn: conn} do conn = put_req_header(conn, "accept", "text/html") diff --git a/test/web/twitter_api/remote_follow_controller_test.exs b/test/web/twitter_api/remote_follow_controller_test.exs index 73062f18f..5c6087527 100644 --- a/test/web/twitter_api/remote_follow_controller_test.exs +++ b/test/web/twitter_api/remote_follow_controller_test.exs @@ -17,9 +17,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do :ok end - clear_config_all([:instance, :federating]) do - Config.put([:instance, :federating], true) - end + clear_config_all([:instance, :federating], true) clear_config([:instance]) clear_config([:frontend_configurations, :pleroma_fe]) diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 14eed5f27..0e787715a 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -117,9 +117,7 @@ test "it registers a new user and parses mentions in the bio" do end describe "register with one time token" do - clear_config([:instance, :registrations_open]) do - Pleroma.Config.put([:instance, :registrations_open], false) - end + clear_config([:instance, :registrations_open], false) test "returns user on success" do {:ok, invite} = UserInviteToken.create_invite() @@ -184,9 +182,7 @@ test "returns error on expired token" do end describe "registers with date limited token" do - clear_config([:instance, :registrations_open]) do - Pleroma.Config.put([:instance, :registrations_open], false) - end + clear_config([:instance, :registrations_open], false) setup do data = %{ @@ -246,9 +242,7 @@ test "returns an error on overdue date", %{data: data} do end describe "registers with reusable token" do - clear_config([:instance, :registrations_open]) do - Pleroma.Config.put([:instance, :registrations_open], false) - end + clear_config([:instance, :registrations_open], false) test "returns user on success, after him registration fails" do {:ok, invite} = UserInviteToken.create_invite(%{max_use: 100}) @@ -292,9 +286,7 @@ test "returns user on success, after him registration fails" do end describe "registers with reusable date limited token" do - clear_config([:instance, :registrations_open]) do - Pleroma.Config.put([:instance, :registrations_open], false) - end + clear_config([:instance, :registrations_open], false) test "returns user on success" do {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100}) diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs index 9d757b5ef..71ecd1aa7 100644 --- a/test/web/twitter_api/util_controller_test.exs +++ b/test/web/twitter_api/util_controller_test.exs @@ -427,9 +427,7 @@ test "it returns version in json format", %{conn: conn} do end describe "POST /main/ostatus - remote_subscribe/2" do - clear_config([:instance, :federating]) do - Config.put([:instance, :federating], true) - end + clear_config([:instance, :federating], true) test "renders subscribe form", %{conn: conn} do user = insert(:user) diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/web/web_finger/web_finger_controller_test.exs index b65bf5904..fcf14dc1e 100644 --- a/test/web/web_finger/web_finger_controller_test.exs +++ b/test/web/web_finger/web_finger_controller_test.exs @@ -14,9 +14,7 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do :ok end - clear_config_all([:instance, :federating]) do - Pleroma.Config.put([:instance, :federating], true) - end + clear_config_all([:instance, :federating], true) test "GET host-meta" do response = From a8c6933ca023d7487910a0f99aed62fa8c2d45e2 Mon Sep 17 00:00:00 2001 From: stwf Date: Thu, 19 Mar 2020 12:25:36 -0400 Subject: [PATCH 10/17] remove federated testing --- .gitlab-ci.yml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d0d3316a..1b7c03ebb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -62,19 +62,21 @@ unit-testing: - mix ecto.migrate - mix coveralls --preload-modules -federated-testing: - stage: test - cache: *testing_cache_policy - services: - - name: minibikini/postgres-with-rum:12 - alias: postgres - command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] - script: - - mix deps.get - - mix ecto.create - - mix ecto.migrate - - epmd -daemon - - mix test --trace --only federated +# Removed to fix CI issue. In this early state it wasn't adding much value anyway. +# TODO Fix and reinstate federated testing +# federated-testing: +# stage: test +# cache: *testing_cache_policy +# services: +# - name: minibikini/postgres-with-rum:12 +# alias: postgres +# command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] +# script: +# - mix deps.get +# - mix ecto.create +# - mix ecto.migrate +# - epmd -daemon +# - mix test --trace --only federated unit-testing-rum: stage: test From 98a60df41f8a053005a2a413b552a582a879ecaa Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Wed, 18 Mar 2020 17:37:54 +0300 Subject: [PATCH 11/17] include_types parameter in /api/v1/notifications --- CHANGELOG.md | 7 +++ docs/API/differences_in_mastoapi_responses.md | 1 + lib/pleroma/web/mastodon_api/mastodon_api.ex | 24 +++++++--- .../web/nodeinfo/nodeinfo_controller.ex | 1 + .../notification_controller_test.exs | 45 +++++++++++++++++++ 5 files changed, 71 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3be2ea08..a27200895 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Removed - **Breaking:** removed `with_move` parameter from notifications timeline. +### Added +- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list. +
+ API Changes +- Mastodon API: Support for `include_types` in `/api/v1/notifications`. +
+ ## [2.0.0] - 2019-03-08 ### Security - Mastodon API: Fix being able to request enourmous amount of statuses in timelines leading to DoS. Now limited to 40 per request. diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md index b12d3092c..dc8f54d2a 100644 --- a/docs/API/differences_in_mastoapi_responses.md +++ b/docs/API/differences_in_mastoapi_responses.md @@ -117,6 +117,7 @@ The `type` value is `pleroma:emoji_reaction`. Has these fields: Accepts additional parameters: - `exclude_visibilities`: will exclude the notifications for activities with the given visibilities. The parameter accepts an array of visibility types (`public`, `unlisted`, `private`, `direct`). Usage example: `GET /api/v1/notifications?exclude_visibilities[]=direct&exclude_visibilities[]=private`. +- `include_types`: will include the notifications for activities with the given types. The parameter accepts an array of types (`mention`, `follow`, `reblog`, `favourite`, `move`, `pleroma:emoji_reaction`). Usage example: `GET /api/v1/notifications?include_types[]=mention&include_types[]=reblog`. ## POST `/api/v1/statuses` diff --git a/lib/pleroma/web/mastodon_api/mastodon_api.ex b/lib/pleroma/web/mastodon_api/mastodon_api.ex index a2dc9bc71..70da64a7a 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api.ex @@ -55,6 +55,7 @@ def get_notifications(user, params \\ %{}) do user |> Notification.for_user_query(options) + |> restrict(:include_types, options) |> restrict(:exclude_types, options) |> restrict(:account_ap_id, options) |> Pagination.fetch_paginated(params) @@ -69,6 +70,7 @@ def get_scheduled_activities(user, params \\ %{}) do defp cast_params(params) do param_types = %{ exclude_types: {:array, :string}, + include_types: {:array, :string}, exclude_visibilities: {:array, :string}, reblogs: :boolean, with_muted: :boolean, @@ -79,14 +81,16 @@ defp cast_params(params) do changeset.changes end - defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do - ap_types = - mastodon_types - |> Enum.map(&Activity.from_mastodon_notification_type/1) - |> Enum.filter(& &1) + defp restrict(query, :include_types, %{include_types: mastodon_types = [_ | _]}) do + ap_types = convert_and_filter_mastodon_types(mastodon_types) - query - |> where([q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data)) + where(query, [q, a], fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data)) + end + + defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do + ap_types = convert_and_filter_mastodon_types(mastodon_types) + + where(query, [q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data)) end defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do @@ -94,4 +98,10 @@ defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do end defp restrict(query, _, _), do: query + + defp convert_and_filter_mastodon_types(types) do + types + |> Enum.map(&Activity.from_mastodon_notification_type/1) + |> Enum.filter(& &1) + end end diff --git a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex index 18eb41333..30838b1eb 100644 --- a/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex +++ b/lib/pleroma/web/nodeinfo/nodeinfo_controller.ex @@ -60,6 +60,7 @@ def raw_nodeinfo do "pleroma_explicit_addressing", "shareable_emoji_packs", "multifetch", + "pleroma:api/v1/notifications:include_types_filter", if Config.get([:media_proxy, :enabled]) do "media_proxy" end, diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs index dbe9a7fd7..7a0011646 100644 --- a/test/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/web/mastodon_api/controllers/notification_controller_test.exs @@ -304,6 +304,51 @@ test "filters notifications using exclude_types" do assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200) end + test "filters notifications using include_types" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + other_user = insert(:user) + + {:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"}) + {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) + {:ok, favorite_activity, _} = CommonAPI.favorite(create_activity.id, other_user) + {:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user) + {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user) + + mention_notification_id = get_notification_id_by_activity(mention_activity) + favorite_notification_id = get_notification_id_by_activity(favorite_activity) + reblog_notification_id = get_notification_id_by_activity(reblog_activity) + follow_notification_id = get_notification_id_by_activity(follow_activity) + + conn_res = get(conn, "/api/v1/notifications", %{include_types: ["follow"]}) + + assert [%{"id" => ^follow_notification_id}] = json_response(conn_res, 200) + + conn_res = get(conn, "/api/v1/notifications", %{include_types: ["mention"]}) + + assert [%{"id" => ^mention_notification_id}] = json_response(conn_res, 200) + + conn_res = get(conn, "/api/v1/notifications", %{include_types: ["favourite"]}) + + assert [%{"id" => ^favorite_notification_id}] = json_response(conn_res, 200) + + conn_res = get(conn, "/api/v1/notifications", %{include_types: ["reblog"]}) + + assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200) + + result = conn |> get("/api/v1/notifications") |> json_response(200) + + assert length(result) == 4 + + result = + conn + |> get("/api/v1/notifications", %{ + include_types: ["follow", "mention", "favourite", "reblog"] + }) + |> json_response(200) + + assert length(result) == 4 + end + test "destroy multiple" do %{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"]) other_user = insert(:user) From fe15f0ba15d02809fa4c21fb646e65d06060f3bb Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Fri, 20 Mar 2020 13:04:37 +0300 Subject: [PATCH 12/17] restrict_unauthenticated setting --- CHANGELOG.md | 1 + config/config.exs | 5 + config/description.exs | 60 +++++ docs/configuration/cheatsheet.md | 18 ++ lib/pleroma/user.ex | 13 +- lib/pleroma/web/activity_pub/visibility.ex | 14 +- .../controllers/account_controller.ex | 7 +- .../controllers/status_controller.ex | 2 +- .../controllers/timeline_controller.ex | 35 ++- .../controllers/account_controller_test.exs | 213 +++++++++++++++++- .../controllers/status_controller_test.exs | 169 ++++++++++++++ .../controllers/timeline_controller_test.exs | 111 ++++++++- 12 files changed, 615 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a27200895..15a073c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list. +- Configuration: `:restrict_unauthenticated` setting, restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses.
API Changes - Mastodon API: Support for `include_types` in `/api/v1/notifications`. diff --git a/config/config.exs b/config/config.exs index 3357e23e7..2ab939107 100644 --- a/config/config.exs +++ b/config/config.exs @@ -624,6 +624,11 @@ parameters: [gin_fuzzy_search_limit: "500"], prepare: :unnamed +config :pleroma, :restrict_unauthenticated, + timelines: %{local: false, federated: false}, + profiles: %{local: false, remote: false}, + activities: %{local: false, remote: false} + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --git a/config/description.exs b/config/description.exs index 732c76734..3781fb9cb 100644 --- a/config/description.exs +++ b/config/description.exs @@ -2915,5 +2915,65 @@ suggestions: [2] } ] + }, + %{ + group: :pleroma, + key: :restrict_unauthenticated, + type: :group, + description: + "Disallow viewing timelines, user profiles and statuses for unauthenticated users.", + children: [ + %{ + key: :timelines, + type: :map, + description: "Settings for public and federated timelines.", + children: [ + %{ + key: :local, + type: :boolean, + description: "Disallow view public timeline." + }, + %{ + key: :federated, + type: :boolean, + description: "Disallow view federated timeline." + } + ] + }, + %{ + key: :profiles, + type: :map, + description: "Settings for user profiles.", + children: [ + %{ + key: :local, + type: :boolean, + description: "Disallow view local user profiles." + }, + %{ + key: :remote, + type: :boolean, + description: "Disallow view remote user profiles." + } + ] + }, + %{ + key: :activities, + type: :map, + description: "Settings for statuses.", + children: [ + %{ + key: :local, + type: :boolean, + description: "Disallow view local statuses." + }, + %{ + key: :remote, + type: :boolean, + description: "Disallow view remote statuses." + } + ] + } + ] } ] diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index 4012fe9b1..d16435e11 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -872,3 +872,21 @@ config :auto_linker, ## :configurable_from_database Boolean, enables/disables in-database configuration. Read [Transfering the config to/from the database](../administration/CLI_tasks/config.md) for more information. + + + +## Restrict entities access for unauthenticated users + +### :restrict_unauthenticated + +Restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses. + +* `timelines` - public and federated timelines + * `local` - public timeline + * `federated` +* `profiles` - user profiles + * `local` + * `remote` +* `activities` - statuses + * `local` + * `remote` \ No newline at end of file diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 911dde6e2..8693c0b80 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -237,7 +237,18 @@ 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{id: user_id}, %User{id: user_id}), do: true + + def visible_for?(%User{local: local} = user, nil) do + cfg_key = + if local, + do: :local, + else: :remote + + if Config.get([:restrict_unauthenticated, :profiles, cfg_key]), + do: false, + else: account_status(user) == :active + end def visible_for?(%User{} = user, for_user) do account_status(user) == :active || superuser?(for_user) diff --git a/lib/pleroma/web/activity_pub/visibility.ex b/lib/pleroma/web/activity_pub/visibility.ex index 6f226fc92..453a6842e 100644 --- a/lib/pleroma/web/activity_pub/visibility.ex +++ b/lib/pleroma/web/activity_pub/visibility.ex @@ -44,6 +44,7 @@ def is_direct?(activity) do def is_list?(%{data: %{"listMessage" => _}}), do: true def is_list?(_), do: false + @spec visible_for_user?(Activity.t(), User.t() | nil) :: boolean() def visible_for_user?(%{actor: ap_id}, %User{ap_id: ap_id}), do: true def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{} = user) do @@ -55,14 +56,21 @@ def visible_for_user?(%{data: %{"listMessage" => list_ap_id}} = activity, %User{ def visible_for_user?(%{data: %{"listMessage" => _}}, nil), do: false - def visible_for_user?(activity, nil) do - is_public?(activity) + def visible_for_user?(%{local: local} = activity, nil) do + cfg_key = + if local, + do: :local, + else: :remote + + if Pleroma.Config.get([:restrict_unauthenticated, :activities, cfg_key]), + do: false, + else: is_public?(activity) end def visible_for_user?(activity, user) do x = [user.ap_id | User.following(user)] y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || []) - visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y)) + is_public?(activity) || Enum.any?(x, &(&1 in y)) end def entire_thread_visible_for_user?(%Activity{} = activity, %User{} = user) do diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 88c997b9f..6dbf11ac9 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -60,7 +60,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do plug( Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug - when action != :create + when action not in [:create, :show, :statuses] ) @relations [:follow, :unfollow] @@ -259,7 +259,8 @@ def show(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do @doc "GET /api/v1/accounts/:id/statuses" def statuses(%{assigns: %{user: reading_user}} = conn, params) do - with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user) do + with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user), + true <- User.visible_for?(user, reading_user) do params = params |> Map.put("tag", params["tagged"]) @@ -271,6 +272,8 @@ def statuses(%{assigns: %{user: reading_user}} = conn, params) do |> add_link_headers(activities) |> put_view(StatusView) |> render("index.json", activities: activities, for: reading_user, as: :activity) + else + _e -> render_error(conn, :not_found, "Can't find user") end end diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index 5c90065f6..37afe6949 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -76,7 +76,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do %{scopes: ["write:bookmarks"]} when action in [:bookmark, :unbookmark] ) - plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug) + plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action not in [:index, :show]) @rate_limited_status_actions ~w(reblog unreblog favourite unfavourite create delete)a diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex index 09e08271b..91f41416d 100644 --- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex @@ -27,7 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct]) plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list) - plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug) + plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action != :public) plug(:put_view, Pleroma.Web.MastodonAPI.StatusView) @@ -75,17 +75,30 @@ def direct(%{assigns: %{user: user}} = conn, params) do def public(%{assigns: %{user: user}} = conn, params) do local_only = truthy_param?(params["local"]) - activities = - params - |> Map.put("type", ["Create", "Announce"]) - |> Map.put("local_only", local_only) - |> Map.put("blocking_user", user) - |> Map.put("muting_user", user) - |> ActivityPub.fetch_public_activities() + cfg_key = + if local_only do + :local + else + :federated + end - conn - |> add_link_headers(activities, %{"local" => local_only}) - |> render("index.json", activities: activities, for: user, as: :activity) + restrict? = Pleroma.Config.get([:restrict_unauthenticated, :timelines, cfg_key]) + + if not (restrict? and is_nil(user)) do + activities = + params + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("local_only", local_only) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> ActivityPub.fetch_public_activities() + + conn + |> add_link_headers(activities, %{"local" => local_only}) + |> render("index.json", activities: activities, for: user, as: :activity) + else + render_error(conn, :unauthorized, "authorization required for timeline view") + end end def hashtag_fetching(params, user, local_only) do diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index 7efccd9c4..2182dd28e 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -5,6 +5,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do use Pleroma.Web.ConnCase + alias Pleroma.Config alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub @@ -46,7 +47,7 @@ test "works by nickname" do end test "works by nickname for remote users" do - Pleroma.Config.put([:instance, :limit_to_local_content], false) + Config.put([:instance, :limit_to_local_content], false) user = insert(:user, nickname: "user@example.com", local: false) conn = @@ -58,7 +59,7 @@ test "works by nickname for remote users" do end test "respects limit_to_local_content == :all for remote user nicknames" do - Pleroma.Config.put([:instance, :limit_to_local_content], :all) + Config.put([:instance, :limit_to_local_content], :all) user = insert(:user, nickname: "user@example.com", local: false) @@ -70,7 +71,7 @@ test "respects limit_to_local_content == :all for remote user nicknames" do end test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do - Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated) + Config.put([:instance, :limit_to_local_content], :unauthenticated) user = insert(:user, nickname: "user@example.com", local: false) reading_user = insert(:user) @@ -140,6 +141,106 @@ test "returns 404 for internal.fetch actor", %{conn: conn} do end end + defp local_and_remote_users do + local = insert(:user) + remote = insert(:user, local: false) + {:ok, local: local, remote: remote} + end + + describe "user fetching with restrict unauthenticated profiles for local and remote" do + setup do: local_and_remote_users() + + clear_config([:restrict_unauthenticated, :profiles, :local]) do + Config.put([:restrict_unauthenticated, :profiles, :local], true) + end + + clear_config([:restrict_unauthenticated, :profiles, :remote]) do + Config.put([:restrict_unauthenticated, :profiles, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + end + + describe "user fetching with restrict unauthenticated profiles for local" do + setup do: local_and_remote_users() + + clear_config([:restrict_unauthenticated, :profiles, :local]) do + Config.put([:restrict_unauthenticated, :profiles, :local], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + end + + describe "user fetching with restrict unauthenticated profiles for remote" do + setup do: local_and_remote_users() + + clear_config([:restrict_unauthenticated, :profiles, :remote]) do + Config.put([:restrict_unauthenticated, :profiles, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + end + describe "user timelines" do setup do: oauth_access(["read:statuses"]) @@ -293,6 +394,110 @@ test "the user views their own timelines and excludes direct messages", %{ end end + defp local_and_remote_activities(%{local: local, remote: remote}) do + insert(:note_activity, user: local) + insert(:note_activity, user: remote, local: false) + + :ok + end + + describe "statuses with restrict unauthenticated profiles for local and remote" do + setup do: local_and_remote_users() + setup :local_and_remote_activities + + clear_config([:restrict_unauthenticated, :profiles, :local]) do + Config.put([:restrict_unauthenticated, :profiles, :local], true) + end + + clear_config([:restrict_unauthenticated, :profiles, :remote]) do + Config.put([:restrict_unauthenticated, :profiles, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + end + end + + describe "statuses with restrict unauthenticated profiles for local" do + setup do: local_and_remote_users() + setup :local_and_remote_activities + + clear_config([:restrict_unauthenticated, :profiles, :local]) do + Config.put([:restrict_unauthenticated, :profiles, :local], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + end + end + + describe "statuses with restrict unauthenticated profiles for remote" do + setup do: local_and_remote_users() + setup :local_and_remote_activities + + clear_config([:restrict_unauthenticated, :profiles, :remote]) do + Config.put([:restrict_unauthenticated, :profiles, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response(res_conn, 200)) == 1 + end + end + describe "followers" do setup do: oauth_access(["read:accounts"]) @@ -757,7 +962,7 @@ test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_ describe "create account by app / rate limit" do clear_config([:rate_limit, :app_account_creation]) do - Pleroma.Config.put([:rate_limit, :app_account_creation], {10_000, 2}) + Config.put([:rate_limit, :app_account_creation], {10_000, 2}) end test "respects rate limit setting", %{conn: conn} do diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs index fbf63f608..81513a429 100644 --- a/test/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/web/mastodon_api/controllers/status_controller_test.exs @@ -476,6 +476,103 @@ test "get a status" do assert id == to_string(activity.id) end + defp local_and_remote_activities do + local = insert(:note_activity) + remote = insert(:note_activity, local: false) + {:ok, local: local, remote: remote} + end + + describe "status with restrict unauthenticated activities for local and remote" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :activities, :local]) do + Config.put([:restrict_unauthenticated, :activities, :local], true) + end + + clear_config([:restrict_unauthenticated, :activities, :remote]) do + Config.put([:restrict_unauthenticated, :activities, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Record not found" + } + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Record not found" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + end + + describe "status with restrict unauthenticated activities for local" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :activities, :local]) do + Config.put([:restrict_unauthenticated, :activities, :local], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Record not found" + } + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + end + + describe "status with restrict unauthenticated activities for remote" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :activities, :remote]) do + Config.put([:restrict_unauthenticated, :activities, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + + assert json_response(res_conn, :not_found) == %{ + "error" => "Record not found" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response(res_conn, 200) + end + end + test "getting a status that doesn't exist returns 404" do %{conn: conn} = oauth_access(["read:statuses"]) activity = insert(:note_activity) @@ -514,6 +611,78 @@ test "get statuses by IDs" do assert [%{"id" => ^id1}, %{"id" => ^id2}] = Enum.sort_by(json_response(conn, :ok), & &1["id"]) end + describe "getting statuses by ids with restricted unauthenticated for local and remote" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :activities, :local]) do + Config.put([:restrict_unauthenticated, :activities, :local], true) + end + + clear_config([:restrict_unauthenticated, :activities, :remote]) do + Config.put([:restrict_unauthenticated, :activities, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) + + assert json_response(res_conn, 200) == [] + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) + + assert length(json_response(res_conn, 200)) == 2 + end + end + + describe "getting statuses by ids with restricted unauthenticated for local" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :activities, :local]) do + Config.put([:restrict_unauthenticated, :activities, :local], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) + + remote_id = remote.id + assert [%{"id" => ^remote_id}] = json_response(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) + + assert length(json_response(res_conn, 200)) == 2 + end + end + + describe "getting statuses by ids with restricted unauthenticated for remote" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :activities, :remote]) do + Config.put([:restrict_unauthenticated, :activities, :remote], true) + end + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) + + local_id = local.id + assert [%{"id" => ^local_id}] = json_response(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) + + assert length(json_response(res_conn, 200)) == 2 + end + end + describe "deleting a status" do test "when you created it" do %{user: author, conn: conn} = oauth_access(["write:statuses"]) diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs index 2c03b0a75..a15c759d4 100644 --- a/test/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs @@ -12,8 +12,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do alias Pleroma.User alias Pleroma.Web.CommonAPI - clear_config([:instance, :public]) - setup do mock(fn env -> apply(HttpRequestMock, :request, [env]) end) :ok @@ -80,15 +78,6 @@ test "the public timeline", %{conn: conn} do assert [%{"content" => "test"}] = json_response(conn, :ok) end - test "the public timeline when public is set to false", %{conn: conn} do - Config.put([:instance, :public], false) - - assert %{"error" => "This resource requires authentication."} == - conn - |> get("/api/v1/timelines/public", %{"local" => "False"}) - |> json_response(:forbidden) - end - test "the public timeline includes only public statuses for an authenticated user" do %{user: user, conn: conn} = oauth_access(["read:statuses"]) @@ -102,6 +91,106 @@ test "the public timeline includes only public statuses for an authenticated use end end + defp local_and_remote_activities do + insert(:note_activity) + insert(:note_activity, local: false) + :ok + end + + describe "public with restrict unauthenticated timeline for local and federated timelines" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :timelines, :local]) do + Config.put([:restrict_unauthenticated, :timelines, :local], true) + end + + clear_config([:restrict_unauthenticated, :timelines, :federated]) do + Config.put([:restrict_unauthenticated, :timelines, :federated], true) + end + + test "if user is unauthenticated", %{conn: conn} do + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) + + assert json_response(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"}) + + assert json_response(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + end + + test "if user is authenticated" do + %{conn: conn} = oauth_access(["read:statuses"]) + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"}) + assert length(json_response(res_conn, 200)) == 2 + end + end + + describe "public with restrict unauthenticated timeline for local" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :timelines, :local]) do + Config.put([:restrict_unauthenticated, :timelines, :local], true) + end + + test "if user is unauthenticated", %{conn: conn} do + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) + + assert json_response(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"}) + assert length(json_response(res_conn, 200)) == 2 + end + + test "if user is authenticated", %{conn: _conn} do + %{conn: conn} = oauth_access(["read:statuses"]) + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"}) + assert length(json_response(res_conn, 200)) == 2 + end + end + + describe "public with restrict unauthenticated timeline for remote" do + setup do: local_and_remote_activities() + + clear_config([:restrict_unauthenticated, :timelines, :federated]) do + Config.put([:restrict_unauthenticated, :timelines, :federated], true) + end + + test "if user is unauthenticated", %{conn: conn} do + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"}) + + assert json_response(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + end + + test "if user is authenticated", %{conn: _conn} do + %{conn: conn} = oauth_access(["read:statuses"]) + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) + assert length(json_response(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "false"}) + assert length(json_response(res_conn, 200)) == 2 + end + end + describe "direct" do test "direct timeline", %{conn: conn} do user_one = insert(:user) From 1c05f539aaea32fe993e5299e656aa44c322e8de Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 20 Mar 2020 18:33:00 +0300 Subject: [PATCH 13/17] Improved in-test `clear_config/n` applicability (setup / setup_all / in-test usage). --- test/activity_expiration_test.exs | 2 +- test/activity_test.exs | 2 +- test/captcha_test.exs | 3 +- test/config/transfer_task_test.exs | 2 +- test/conversation_test.exs | 2 +- test/emails/mailer_test.exs | 3 +- test/http/request_builder_test.exs | 4 +- test/object/fetcher_test.exs | 5 +- test/object_test.exs | 4 +- .../admin_secret_authentication_plug_test.exs | 2 +- ...sure_public_or_authenticated_plug_test.exs | 2 +- test/plugs/http_security_plug_test.exs | 6 +- test/plugs/instance_static_test.exs | 2 +- test/plugs/oauth_scopes_plug_test.exs | 2 +- test/plugs/rate_limiter_test.exs | 8 +-- test/plugs/remote_ip_test.exs | 3 +- test/plugs/user_enabled_plug_test.exs | 2 +- test/plugs/user_is_admin_plug_test.exs | 4 +- test/repo_test.exs | 2 +- test/scheduled_activity_test.exs | 2 +- test/support/helpers.ex | 58 ++----------------- test/tasks/config_test.exs | 2 +- test/tasks/robots_txt_test.exs | 2 +- .../upload/filter/anonymize_filename_test.exs | 2 +- test/upload/filter/mogrify_test.exs | 2 +- test/upload/filter_test.exs | 2 +- test/upload_test.exs | 2 +- test/uploaders/s3_test.exs | 9 +-- test/user_search_test.exs | 2 +- test/user_test.exs | 29 +++++----- .../activity_pub_controller_test.exs | 8 +-- test/web/activity_pub/activity_pub_test.exs | 6 +- .../mrf/hellthread_policy_test.exs | 2 +- .../activity_pub/mrf/keyword_policy_test.exs | 2 +- .../activity_pub/mrf/mention_policy_test.exs | 2 +- test/web/activity_pub/mrf/mrf_test.exs | 2 +- .../mrf/object_age_policy_test.exs | 9 +-- .../mrf/reject_non_public_test.exs | 2 +- .../activity_pub/mrf/simple_policy_test.exs | 21 +++---- .../activity_pub/mrf/subchain_policy_test.exs | 3 +- .../mrf/user_allowlist_policy_test.exs | 2 +- .../mrf/vocabulary_policy_test.exs | 4 +- test/web/activity_pub/publisher_test.exs | 2 +- test/web/activity_pub/relay_test.exs | 2 +- .../transmogrifier/follow_handling_test.exs | 2 +- test/web/activity_pub/transmogrifier_test.exs | 16 +++-- .../activity_pub/views/object_view_test.exs | 2 +- .../admin_api/admin_api_controller_test.exs | 18 +++--- test/web/chat_channel_test.exs | 2 +- test/web/common_api/common_api_test.exs | 6 +- test/web/federator_test.exs | 9 ++- test/web/feed/tag_controller_test.exs | 2 +- test/web/feed/user_controller_test.exs | 4 +- test/web/instances/instance_test.exs | 2 +- test/web/instances/instances_test.exs | 2 +- test/web/masto_fe_controller_test.exs | 2 +- .../update_credentials_test.exs | 3 +- .../controllers/account_controller_test.exs | 40 ++++--------- .../controllers/media_controller_test.exs | 4 +- .../scheduled_activity_controller_test.exs | 2 +- .../controllers/status_controller_test.exs | 40 ++++--------- .../controllers/timeline_controller_test.exs | 16 ++--- .../media_proxy_controller_test.exs | 4 +- test/web/media_proxy/media_proxy_test.exs | 4 +- test/web/metadata/opengraph_test.exs | 2 +- test/web/metadata/twitter_card_test.exs | 2 +- test/web/node_info_test.exs | 6 +- test/web/oauth/ldap_authorization_test.exs | 4 +- test/web/oauth/oauth_controller_test.exs | 7 +-- test/web/ostatus/ostatus_controller_test.exs | 2 +- .../controllers/account_controller_test.exs | 2 +- .../controllers/emoji_api_controller_test.exs | 3 +- test/web/plugs/federating_plug_test.exs | 2 +- test/web/rich_media/helpers_test.exs | 2 +- .../static_fe/static_fe_controller_test.exs | 5 +- test/web/streamer/streamer_test.exs | 3 +- .../remote_follow_controller_test.exs | 9 ++- test/web/twitter_api/twitter_api_test.exs | 8 +-- test/web/twitter_api/util_controller_test.exs | 8 +-- .../web_finger/web_finger_controller_test.exs | 2 +- .../cron/clear_oauth_token_worker_test.exs | 2 +- .../cron/digest_emails_worker_test.exs | 2 +- .../purge_expired_activities_worker_test.exs | 2 +- .../scheduled_activity_worker_test.exs | 2 +- 84 files changed, 196 insertions(+), 298 deletions(-) diff --git a/test/activity_expiration_test.exs b/test/activity_expiration_test.exs index 4cda5e985..e899d4509 100644 --- a/test/activity_expiration_test.exs +++ b/test/activity_expiration_test.exs @@ -7,7 +7,7 @@ defmodule Pleroma.ActivityExpirationTest do alias Pleroma.ActivityExpiration import Pleroma.Factory - clear_config([ActivityExpiration, :enabled]) + setup do: clear_config([ActivityExpiration, :enabled]) test "finds activities due to be deleted only" do activity = insert(:note_activity) diff --git a/test/activity_test.exs b/test/activity_test.exs index 46b55beaa..0c19f481b 100644 --- a/test/activity_test.exs +++ b/test/activity_test.exs @@ -138,7 +138,7 @@ test "when association is not loaded" do } end - clear_config([:instance, :limit_to_local_content]) + setup do: clear_config([:instance, :limit_to_local_content]) test "finds utf8 text in statuses", %{ japanese_activity: japanese_activity, diff --git a/test/captcha_test.exs b/test/captcha_test.exs index 5e29b48b0..ac1d846e8 100644 --- a/test/captcha_test.exs +++ b/test/captcha_test.exs @@ -12,8 +12,7 @@ defmodule Pleroma.CaptchaTest do alias Pleroma.Captcha.Native @ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}] - - clear_config([Pleroma.Captcha, :enabled]) + setup do: clear_config([Pleroma.Captcha, :enabled]) describe "Kocaptcha" do setup do diff --git a/test/config/transfer_task_test.exs b/test/config/transfer_task_test.exs index 7bfae67bf..0265a6156 100644 --- a/test/config/transfer_task_test.exs +++ b/test/config/transfer_task_test.exs @@ -10,7 +10,7 @@ defmodule Pleroma.Config.TransferTaskTest do alias Pleroma.Config.TransferTask alias Pleroma.ConfigDB - clear_config(:configurable_from_database, true) + setup do: clear_config(:configurable_from_database, true) test "transfer config values from db to env" do refute Application.get_env(:pleroma, :test_key) diff --git a/test/conversation_test.exs b/test/conversation_test.exs index 3c54253e3..056a0e920 100644 --- a/test/conversation_test.exs +++ b/test/conversation_test.exs @@ -11,7 +11,7 @@ defmodule Pleroma.ConversationTest do import Pleroma.Factory - clear_config_all([:instance, :federating], true) + setup_all do: clear_config([:instance, :federating], true) test "it goes through old direct conversations" do user = insert(:user) diff --git a/test/emails/mailer_test.exs b/test/emails/mailer_test.exs index f30aa6a72..e6e34cba8 100644 --- a/test/emails/mailer_test.exs +++ b/test/emails/mailer_test.exs @@ -14,8 +14,7 @@ defmodule Pleroma.Emails.MailerTest do subject: "Pleroma test email", to: [{"Test User", "user1@example.com"}] } - - clear_config([Pleroma.Emails.Mailer, :enabled]) + setup do: clear_config([Pleroma.Emails.Mailer, :enabled]) test "not send email when mailer is disabled" do Pleroma.Config.put([Pleroma.Emails.Mailer, :enabled], false) diff --git a/test/http/request_builder_test.exs b/test/http/request_builder_test.exs index 11a9314ae..bf3a15ebe 100644 --- a/test/http/request_builder_test.exs +++ b/test/http/request_builder_test.exs @@ -8,8 +8,8 @@ defmodule Pleroma.HTTP.RequestBuilderTest do alias Pleroma.HTTP.RequestBuilder describe "headers/2" do - clear_config([:http, :send_user_agent]) - clear_config([:http, :user_agent]) + setup do: clear_config([:http, :send_user_agent]) + setup do: clear_config([:http, :user_agent]) test "don't send pleroma user agent" do assert RequestBuilder.headers(%{}, []) == %{headers: []} diff --git a/test/object/fetcher_test.exs b/test/object/fetcher_test.exs index 4775ee152..c06e91f12 100644 --- a/test/object/fetcher_test.exs +++ b/test/object/fetcher_test.exs @@ -28,8 +28,7 @@ defmodule Pleroma.Object.FetcherTest do describe "max thread distance restriction" do @ap_id "http://mastodon.example.org/@admin/99541947525187367" - - clear_config([:instance, :federation_incoming_replies_max_depth]) + setup do: clear_config([:instance, :federation_incoming_replies_max_depth]) test "it returns thread depth exceeded error if thread depth is exceeded" do Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0) @@ -160,7 +159,7 @@ test "it can refetch pruned objects" do end describe "signed fetches" do - clear_config([:activitypub, :sign_object_fetches]) + setup do: clear_config([:activitypub, :sign_object_fetches]) test_with_mock "it signs fetches when configured to do so", Pleroma.Signature, diff --git a/test/object_test.exs b/test/object_test.exs index 85b2a3f6d..fe583decd 100644 --- a/test/object_test.exs +++ b/test/object_test.exs @@ -74,8 +74,8 @@ test "ensures cache is cleared for the object" do end describe "delete attachments" do - clear_config([Pleroma.Upload]) - clear_config([:instance, :cleanup_attachments]) + setup do: clear_config([Pleroma.Upload]) + setup do: clear_config([:instance, :cleanup_attachments]) test "Disabled via config" do Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local) diff --git a/test/plugs/admin_secret_authentication_plug_test.exs b/test/plugs/admin_secret_authentication_plug_test.exs index 2e300ac0c..100016c62 100644 --- a/test/plugs/admin_secret_authentication_plug_test.exs +++ b/test/plugs/admin_secret_authentication_plug_test.exs @@ -23,7 +23,7 @@ test "does nothing if a user is assigned", %{conn: conn} do end describe "when secret set it assigns an admin user" do - clear_config([:admin_token]) + setup do: clear_config([:admin_token]) test "with `admin_token` query parameter", %{conn: conn} do Pleroma.Config.put(:admin_token, "password123") diff --git a/test/plugs/ensure_public_or_authenticated_plug_test.exs b/test/plugs/ensure_public_or_authenticated_plug_test.exs index 3fcb4d372..411252274 100644 --- a/test/plugs/ensure_public_or_authenticated_plug_test.exs +++ b/test/plugs/ensure_public_or_authenticated_plug_test.exs @@ -9,7 +9,7 @@ defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.User - clear_config([:instance, :public]) + setup do: clear_config([:instance, :public]) test "it halts if not public and no user is assigned", %{conn: conn} do Config.put([:instance, :public], false) diff --git a/test/plugs/http_security_plug_test.exs b/test/plugs/http_security_plug_test.exs index 944a9a139..84e4c274f 100644 --- a/test/plugs/http_security_plug_test.exs +++ b/test/plugs/http_security_plug_test.exs @@ -7,9 +7,9 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do alias Pleroma.Config alias Plug.Conn - clear_config([:http_securiy, :enabled]) - clear_config([:http_security, :sts]) - clear_config([:http_security, :referrer_policy]) + setup do: clear_config([:http_securiy, :enabled]) + setup do: clear_config([:http_security, :sts]) + setup do: clear_config([:http_security, :referrer_policy]) describe "http security enabled" do setup do diff --git a/test/plugs/instance_static_test.exs b/test/plugs/instance_static_test.exs index 2e9d2dc46..b8f070d6a 100644 --- a/test/plugs/instance_static_test.exs +++ b/test/plugs/instance_static_test.exs @@ -12,7 +12,7 @@ defmodule Pleroma.Web.RuntimeStaticPlugTest do on_exit(fn -> File.rm_rf(@dir) end) end - clear_config([:instance, :static_dir], @dir) + setup do: clear_config([:instance, :static_dir], @dir) test "overrides index" do bundled_index = get(build_conn(), "/") diff --git a/test/plugs/oauth_scopes_plug_test.exs b/test/plugs/oauth_scopes_plug_test.exs index 1b3aa85b6..e79ecf263 100644 --- a/test/plugs/oauth_scopes_plug_test.exs +++ b/test/plugs/oauth_scopes_plug_test.exs @@ -193,7 +193,7 @@ test "filters scopes which directly match or are ancestors of supported scopes" end describe "transform_scopes/2" do - clear_config([:auth, :enforce_oauth_admin_scope_usage]) + setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage]) setup do {:ok, %{f: &OAuthScopesPlug.transform_scopes/2}} diff --git a/test/plugs/rate_limiter_test.exs b/test/plugs/rate_limiter_test.exs index c6e494c13..0ce9f3a0a 100644 --- a/test/plugs/rate_limiter_test.exs +++ b/test/plugs/rate_limiter_test.exs @@ -12,14 +12,12 @@ defmodule Pleroma.Plugs.RateLimiterTest do import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2] # Note: each example must work with separate buckets in order to prevent concurrency issues - - clear_config([Pleroma.Web.Endpoint, :http, :ip]) - clear_config(:rate_limit) + setup do: clear_config([Pleroma.Web.Endpoint, :http, :ip]) + setup do: clear_config(:rate_limit) describe "config" do @limiter_name :test_init - - clear_config([Pleroma.Plugs.RemoteIp, :enabled]) + setup do: clear_config([Pleroma.Plugs.RemoteIp, :enabled]) test "config is required for plug to work" do Config.put([:rate_limit, @limiter_name], {1, 1}) diff --git a/test/plugs/remote_ip_test.exs b/test/plugs/remote_ip_test.exs index 9c3737b0b..752ab32e7 100644 --- a/test/plugs/remote_ip_test.exs +++ b/test/plugs/remote_ip_test.exs @@ -9,8 +9,7 @@ defmodule Pleroma.Plugs.RemoteIpTest do alias Pleroma.Plugs.RemoteIp import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2] - - clear_config(RemoteIp) + setup do: clear_config(RemoteIp) test "disabled" do Pleroma.Config.put(RemoteIp, enabled: false) diff --git a/test/plugs/user_enabled_plug_test.exs b/test/plugs/user_enabled_plug_test.exs index 931513d83..b219d8abf 100644 --- a/test/plugs/user_enabled_plug_test.exs +++ b/test/plugs/user_enabled_plug_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.Plugs.UserEnabledPlugTest do alias Pleroma.Plugs.UserEnabledPlug import Pleroma.Factory - clear_config([:instance, :account_activation_required]) + setup do: clear_config([:instance, :account_activation_required]) test "doesn't do anything if the user isn't set", %{conn: conn} do ret_conn = diff --git a/test/plugs/user_is_admin_plug_test.exs b/test/plugs/user_is_admin_plug_test.exs index 1062d6e70..fd6a50e53 100644 --- a/test/plugs/user_is_admin_plug_test.exs +++ b/test/plugs/user_is_admin_plug_test.exs @@ -9,7 +9,7 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do import Pleroma.Factory describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage], false) + setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false) test "accepts a user that is an admin" do user = insert(:user, is_admin: true) @@ -40,7 +40,7 @@ test "denies when a user isn't set" do end describe "with [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage], true) + setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true) setup do admin_user = insert(:user, is_admin: true) diff --git a/test/repo_test.exs b/test/repo_test.exs index 75e85f974..daffc6542 100644 --- a/test/repo_test.exs +++ b/test/repo_test.exs @@ -67,7 +67,7 @@ test "return error if has not assoc " do :ok end - clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check]) + setup do: clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check]) test "raises if it detects unapplied migrations" do assert_raise Pleroma.Repo.UnappliedMigrationsError, fn -> diff --git a/test/scheduled_activity_test.exs b/test/scheduled_activity_test.exs index 4369e7e8a..7faa5660d 100644 --- a/test/scheduled_activity_test.exs +++ b/test/scheduled_activity_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.ScheduledActivityTest do alias Pleroma.ScheduledActivity import Pleroma.Factory - clear_config([ScheduledActivity, :enabled]) + setup do: clear_config([ScheduledActivity, :enabled]) setup context do DataCase.ensure_local_uploader(context) diff --git a/test/support/helpers.ex b/test/support/helpers.ex index c6f7fa5e2..e68e9bfd2 100644 --- a/test/support/helpers.ex +++ b/test/support/helpers.ex @@ -17,12 +17,10 @@ defmacro clear_config(config_path) do defmacro clear_config(config_path, do: yield) do quote do - setup do - initial_setting = Config.get(unquote(config_path)) - unquote(yield) - on_exit(fn -> Config.put(unquote(config_path), initial_setting) end) - :ok - end + initial_setting = Config.get(unquote(config_path)) + unquote(yield) + on_exit(fn -> Config.put(unquote(config_path), initial_setting) end) + :ok end end @@ -34,58 +32,12 @@ defmacro clear_config(config_path, temp_setting) do end end - @doc """ - From _within a test case_, sets config to provided value and restores initial value on exit. - For multi-case setup use `clear_config/2` instead. - """ - def set_config(config_path, temp_setting) do - initial_setting = Config.get(config_path) - Config.put(config_path, temp_setting) - - ExUnit.Callbacks.on_exit(fn -> Config.put(config_path, initial_setting) end) - end - - @doc "Stores initial config value and restores it after *all* test examples are executed." - defmacro clear_config_all(config_path) do - quote do - clear_config_all(unquote(config_path)) do - end - end - end - - @doc """ - Stores initial config value and restores it after *all* test examples are executed. - Only use if *all* test examples should work with the same stubbed value - (*no* examples set a different value). - """ - defmacro clear_config_all(config_path, do: yield) do - quote do - setup_all do - initial_setting = Config.get(unquote(config_path)) - unquote(yield) - on_exit(fn -> Config.put(unquote(config_path), initial_setting) end) - :ok - end - end - end - - defmacro clear_config_all(config_path, temp_setting) do - quote do - clear_config_all(unquote(config_path)) do - Config.put(unquote(config_path), unquote(temp_setting)) - end - end - end - defmacro __using__(_opts) do quote do import Pleroma.Tests.Helpers, only: [ clear_config: 1, - clear_config: 2, - clear_config_all: 1, - clear_config_all: 2, - set_config: 2 + clear_config: 2 ] def to_datetime(naive_datetime) do diff --git a/test/tasks/config_test.exs b/test/tasks/config_test.exs index b0c2efc98..3dee4f082 100644 --- a/test/tasks/config_test.exs +++ b/test/tasks/config_test.exs @@ -20,7 +20,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do :ok end - clear_config_all(:configurable_from_database, true) + setup_all do: clear_config(:configurable_from_database, true) test "error if file with custom settings doesn't exist" do Mix.Tasks.Pleroma.Config.migrate_to_db("config/not_existance_config_file.exs") diff --git a/test/tasks/robots_txt_test.exs b/test/tasks/robots_txt_test.exs index e03c9c192..7040a0e4e 100644 --- a/test/tasks/robots_txt_test.exs +++ b/test/tasks/robots_txt_test.exs @@ -7,7 +7,7 @@ defmodule Mix.Tasks.Pleroma.RobotsTxtTest do use Pleroma.Tests.Helpers alias Mix.Tasks.Pleroma.RobotsTxt - clear_config([:instance, :static_dir]) + setup do: clear_config([:instance, :static_dir]) test "creates new dir" do path = "test/fixtures/new_dir/" diff --git a/test/upload/filter/anonymize_filename_test.exs b/test/upload/filter/anonymize_filename_test.exs index 330158580..2d5c580f1 100644 --- a/test/upload/filter/anonymize_filename_test.exs +++ b/test/upload/filter/anonymize_filename_test.exs @@ -18,7 +18,7 @@ defmodule Pleroma.Upload.Filter.AnonymizeFilenameTest do %{upload_file: upload_file} end - clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text]) + setup do: clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text]) test "it replaces filename on pre-defined text", %{upload_file: upload_file} do Config.put([Upload.Filter.AnonymizeFilename, :text], "custom-file.png") diff --git a/test/upload/filter/mogrify_test.exs b/test/upload/filter/mogrify_test.exs index 52483d80c..b6a463e8c 100644 --- a/test/upload/filter/mogrify_test.exs +++ b/test/upload/filter/mogrify_test.exs @@ -10,7 +10,7 @@ defmodule Pleroma.Upload.Filter.MogrifyTest do alias Pleroma.Upload alias Pleroma.Upload.Filter - clear_config([Filter.Mogrify, :args]) + setup do: clear_config([Filter.Mogrify, :args]) test "apply mogrify filter" do Config.put([Filter.Mogrify, :args], [{"tint", "40"}]) diff --git a/test/upload/filter_test.exs b/test/upload/filter_test.exs index 2ffc5247b..352b66402 100644 --- a/test/upload/filter_test.exs +++ b/test/upload/filter_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.Upload.FilterTest do alias Pleroma.Config alias Pleroma.Upload.Filter - clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text]) + setup do: clear_config([Pleroma.Upload.Filter.AnonymizeFilename, :text]) test "applies filters" do Config.put([Pleroma.Upload.Filter.AnonymizeFilename, :text], "custom-file.png") diff --git a/test/upload_test.exs b/test/upload_test.exs index 6bf7f2417..060a940bb 100644 --- a/test/upload_test.exs +++ b/test/upload_test.exs @@ -250,7 +250,7 @@ test "escapes reserved uri characters" do end describe "Setting a custom base_url for uploaded media" do - clear_config([Pleroma.Upload, :base_url], "https://cache.pleroma.social") + setup do: clear_config([Pleroma.Upload, :base_url], "https://cache.pleroma.social") test "returns a media url with configured base_url" do base_url = Pleroma.Config.get([Pleroma.Upload, :base_url]) diff --git a/test/uploaders/s3_test.exs b/test/uploaders/s3_test.exs index 96c21c0e5..6950ccb25 100644 --- a/test/uploaders/s3_test.exs +++ b/test/uploaders/s3_test.exs @@ -11,10 +11,11 @@ defmodule Pleroma.Uploaders.S3Test do import Mock import ExUnit.CaptureLog - clear_config(Pleroma.Uploaders.S3, - bucket: "test_bucket", - public_endpoint: "https://s3.amazonaws.com" - ) + setup do: + clear_config(Pleroma.Uploaders.S3, + bucket: "test_bucket", + public_endpoint: "https://s3.amazonaws.com" + ) describe "get_file/1" do test "it returns path to local folder for files" do diff --git a/test/user_search_test.exs b/test/user_search_test.exs index 406cc8fb2..cb847b516 100644 --- a/test/user_search_test.exs +++ b/test/user_search_test.exs @@ -15,7 +15,7 @@ defmodule Pleroma.UserSearchTest do end describe "User.search" do - clear_config([:instance, :limit_to_local_content]) + setup do: clear_config([:instance, :limit_to_local_content]) test "excluded invisible users from results" do user = insert(:user, %{nickname: "john t1000"}) diff --git a/test/user_test.exs b/test/user_test.exs index e0e7a26b8..119a36ec1 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -24,7 +24,7 @@ defmodule Pleroma.UserTest do :ok end - clear_config([:instance, :account_activation_required]) + setup do: clear_config([:instance, :account_activation_required]) describe "service actors" do test "returns updated invisible actor" do @@ -297,7 +297,7 @@ test "local users do not automatically follow local locked accounts" do end describe "unfollow/2" do - clear_config([:instance, :external_user_synchronization]) + setup do: clear_config([:instance, :external_user_synchronization]) test "unfollow with syncronizes external user" do Pleroma.Config.put([:instance, :external_user_synchronization], true) @@ -375,10 +375,9 @@ test "fetches correct profile for nickname beginning with number" do password_confirmation: "test", email: "email@example.com" } - - clear_config([:instance, :autofollowed_nicknames]) - clear_config([:instance, :welcome_message]) - clear_config([:instance, :welcome_user_nickname]) + setup do: clear_config([:instance, :autofollowed_nicknames]) + setup do: clear_config([:instance, :welcome_message]) + setup do: clear_config([:instance, :welcome_user_nickname]) test "it autofollows accounts that are set for it" do user = insert(:user) @@ -412,7 +411,7 @@ test "it sends a welcome message if it is set" do assert activity.actor == welcome_user.ap_id end - clear_config([:instance, :account_activation_required]) + setup do: clear_config([:instance, :account_activation_required]) test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do Pleroma.Config.put([:instance, :account_activation_required], true) @@ -475,8 +474,7 @@ test "it sets the password_hash and ap_id" do password_confirmation: "test", email: "email@example.com" } - - clear_config([:instance, :account_activation_required], true) + setup do: clear_config([:instance, :account_activation_required], true) test "it creates unconfirmed user" do changeset = User.register_changeset(%User{}, @full_user_data) @@ -619,9 +617,8 @@ test "returns an ap_followers link for a user" do ap_id: "http...", avatar: %{some: "avatar"} } - - clear_config([:instance, :user_bio_length]) - clear_config([:instance, :user_name_length]) + setup do: clear_config([:instance, :user_bio_length]) + setup do: clear_config([:instance, :user_name_length]) test "it confirms validity" do cs = User.remote_user_creation(@valid_remote) @@ -1114,7 +1111,7 @@ test "hide a user's statuses from timelines and notifications" do [user: user] end - clear_config([:instance, :federating]) + setup do: clear_config([:instance, :federating]) test ".delete_user_activities deletes all create activities", %{user: user} do {:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"}) @@ -1295,7 +1292,7 @@ test "User.delete() plugs any possible zombie objects" do end describe "account_status/1" do - clear_config([:instance, :account_activation_required]) + setup do: clear_config([:instance, :account_activation_required]) test "return confirmation_pending for unconfirm user" do Pleroma.Config.put([:instance, :account_activation_required], true) @@ -1663,7 +1660,7 @@ test "performs update cache if user updated" do end describe "following/followers synchronization" do - clear_config([:instance, :external_user_synchronization]) + setup do: clear_config([:instance, :external_user_synchronization]) test "updates the counters normally on following/getting a follow when disabled" do Pleroma.Config.put([:instance, :external_user_synchronization], false) @@ -1768,7 +1765,7 @@ test "changes email", %{user: user} do [local_user: local_user, remote_user: remote_user] end - clear_config([:instance, :limit_to_local_content]) + setup do: clear_config([:instance, :limit_to_local_content]) test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{ remote_user: remote_user diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index df0c53458..573853afa 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -26,10 +26,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do :ok end - clear_config([:instance, :federating], true) + setup do: clear_config([:instance, :federating], true) describe "/relay" do - clear_config([:instance, :allow_relay]) + setup do: clear_config([:instance, :allow_relay]) test "with the relay active, it returns the relay user", %{conn: conn} do res = @@ -1225,8 +1225,8 @@ test "GET /api/ap/whoami", %{conn: conn} do |> json_response(403) end - clear_config([:media_proxy]) - clear_config([Pleroma.Upload]) + setup do: clear_config([:media_proxy]) + setup do: clear_config([Pleroma.Upload]) test "POST /api/ap/upload_media", %{conn: conn} do user = insert(:user) diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index d86c8260e..a43dd34f0 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -27,7 +27,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do :ok end - clear_config([:instance, :federating]) + setup do: clear_config([:instance, :federating]) describe "streaming out participations" do test "it streams them out" do @@ -1396,7 +1396,7 @@ test "creates an undo activity for the last block" do end describe "deletion" do - clear_config([:instance, :rewrite_policy]) + setup do: clear_config([:instance, :rewrite_policy]) test "it reverts deletion on error" do note = insert(:note_activity) @@ -1580,7 +1580,7 @@ test "it filters broken threads" do end describe "update" do - clear_config([:instance, :max_pinned_statuses]) + setup do: clear_config([:instance, :max_pinned_statuses]) test "it creates an update activity with the new user data" do user = insert(:user) diff --git a/test/web/activity_pub/mrf/hellthread_policy_test.exs b/test/web/activity_pub/mrf/hellthread_policy_test.exs index 916b95692..95ef0b168 100644 --- a/test/web/activity_pub/mrf/hellthread_policy_test.exs +++ b/test/web/activity_pub/mrf/hellthread_policy_test.exs @@ -26,7 +26,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do [user: user, message: message] end - clear_config(:mrf_hellthread) + setup do: clear_config(:mrf_hellthread) describe "reject" do test "rejects the message if the recipient count is above reject_threshold", %{ diff --git a/test/web/activity_pub/mrf/keyword_policy_test.exs b/test/web/activity_pub/mrf/keyword_policy_test.exs index 18242a889..fd1f7aec8 100644 --- a/test/web/activity_pub/mrf/keyword_policy_test.exs +++ b/test/web/activity_pub/mrf/keyword_policy_test.exs @@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do alias Pleroma.Web.ActivityPub.MRF.KeywordPolicy - clear_config(:mrf_keyword) + setup do: clear_config(:mrf_keyword) setup do Pleroma.Config.put([:mrf_keyword], %{reject: [], federated_timeline_removal: [], replace: []}) diff --git a/test/web/activity_pub/mrf/mention_policy_test.exs b/test/web/activity_pub/mrf/mention_policy_test.exs index 08f7be542..aa003bef5 100644 --- a/test/web/activity_pub/mrf/mention_policy_test.exs +++ b/test/web/activity_pub/mrf/mention_policy_test.exs @@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicyTest do alias Pleroma.Web.ActivityPub.MRF.MentionPolicy - clear_config(:mrf_mention) + setup do: clear_config(:mrf_mention) test "pass filter if allow list is empty" do Pleroma.Config.delete([:mrf_mention]) diff --git a/test/web/activity_pub/mrf/mrf_test.exs b/test/web/activity_pub/mrf/mrf_test.exs index 04709df17..c941066f2 100644 --- a/test/web/activity_pub/mrf/mrf_test.exs +++ b/test/web/activity_pub/mrf/mrf_test.exs @@ -60,7 +60,7 @@ test "matches are case-insensitive" do end describe "describe/0" do - clear_config([:instance, :rewrite_policy]) + setup do: clear_config([:instance, :rewrite_policy]) test "it works as expected with noop policy" do expected = %{ diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs index bdbbb1fc4..0fbc5f57a 100644 --- a/test/web/activity_pub/mrf/object_age_policy_test.exs +++ b/test/web/activity_pub/mrf/object_age_policy_test.exs @@ -9,10 +9,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy alias Pleroma.Web.ActivityPub.Visibility - clear_config(:mrf_object_age, - threshold: 172_800, - actions: [:delist, :strip_followers] - ) + setup do: + clear_config(:mrf_object_age, + threshold: 172_800, + actions: [:delist, :strip_followers] + ) setup_all do Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) diff --git a/test/web/activity_pub/mrf/reject_non_public_test.exs b/test/web/activity_pub/mrf/reject_non_public_test.exs index fc1d190bb..abfd32df8 100644 --- a/test/web/activity_pub/mrf/reject_non_public_test.exs +++ b/test/web/activity_pub/mrf/reject_non_public_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublicTest do alias Pleroma.Web.ActivityPub.MRF.RejectNonPublic - clear_config([:mrf_rejectnonpublic]) + setup do: clear_config([:mrf_rejectnonpublic]) describe "public message" do test "it's allowed when address is public" do diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs index 97aec6622..5aebbc675 100644 --- a/test/web/activity_pub/mrf/simple_policy_test.exs +++ b/test/web/activity_pub/mrf/simple_policy_test.exs @@ -8,16 +8,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do alias Pleroma.Config alias Pleroma.Web.ActivityPub.MRF.SimplePolicy - clear_config(:mrf_simple, - media_removal: [], - media_nsfw: [], - federated_timeline_removal: [], - report_removal: [], - reject: [], - accept: [], - avatar_removal: [], - banner_removal: [] - ) + setup do: + clear_config(:mrf_simple, + media_removal: [], + media_nsfw: [], + federated_timeline_removal: [], + report_removal: [], + reject: [], + accept: [], + avatar_removal: [], + banner_removal: [] + ) describe "when :media_removal" do test "is empty" do diff --git a/test/web/activity_pub/mrf/subchain_policy_test.exs b/test/web/activity_pub/mrf/subchain_policy_test.exs index 221b8958e..fff66cb7e 100644 --- a/test/web/activity_pub/mrf/subchain_policy_test.exs +++ b/test/web/activity_pub/mrf/subchain_policy_test.exs @@ -13,8 +13,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicyTest do "type" => "Create", "object" => %{"content" => "hi"} } - - clear_config([:mrf_subchain, :match_actor]) + setup do: clear_config([:mrf_subchain, :match_actor]) test "it matches and processes subchains when the actor matches a configured target" do Pleroma.Config.put([:mrf_subchain, :match_actor], %{ diff --git a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs b/test/web/activity_pub/mrf/user_allowlist_policy_test.exs index 87c9e1b29..724bae058 100644 --- a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs +++ b/test/web/activity_pub/mrf/user_allowlist_policy_test.exs @@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do alias Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy - clear_config([:mrf_user_allowlist, :localhost]) + setup do: clear_config([:mrf_user_allowlist, :localhost]) test "pass filter if allow list is empty" do actor = insert(:user) diff --git a/test/web/activity_pub/mrf/vocabulary_policy_test.exs b/test/web/activity_pub/mrf/vocabulary_policy_test.exs index d9207b095..69f22bb77 100644 --- a/test/web/activity_pub/mrf/vocabulary_policy_test.exs +++ b/test/web/activity_pub/mrf/vocabulary_policy_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicyTest do alias Pleroma.Web.ActivityPub.MRF.VocabularyPolicy describe "accept" do - clear_config([:mrf_vocabulary, :accept]) + setup do: clear_config([:mrf_vocabulary, :accept]) test "it accepts based on parent activity type" do Pleroma.Config.put([:mrf_vocabulary, :accept], ["Like"]) @@ -65,7 +65,7 @@ test "it does not accept disallowed parent types" do end describe "reject" do - clear_config([:mrf_vocabulary, :reject]) + setup do: clear_config([:mrf_vocabulary, :reject]) test "it rejects based on parent activity type" do Pleroma.Config.put([:mrf_vocabulary, :reject], ["Like"]) diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs index ed9c951dd..801da03c1 100644 --- a/test/web/activity_pub/publisher_test.exs +++ b/test/web/activity_pub/publisher_test.exs @@ -23,7 +23,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do :ok end - clear_config_all([:instance, :federating], true) + setup_all do: clear_config([:instance, :federating], true) describe "gather_webfinger_links/1" do test "it returns links" do diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs index e3115dcd8..040625e4d 100644 --- a/test/web/activity_pub/relay_test.exs +++ b/test/web/activity_pub/relay_test.exs @@ -68,7 +68,7 @@ test "returns activity" do end describe "publish/1" do - clear_config([:instance, :federating]) + setup do: clear_config([:instance, :federating]) test "returns error when activity not `Create` type" do activity = insert(:like_activity) diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs index c3d3f9830..967389fae 100644 --- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs +++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs @@ -19,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do end describe "handle_incoming" do - clear_config([:user, :deny_follow_blocked]) + setup do: clear_config([:user, :deny_follow_blocked]) test "it works for osada follow request" do user = insert(:user) diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index c025b6b78..b2cabbd30 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -25,7 +25,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do :ok end - clear_config([:instance, :max_remote_account_fields]) + setup do: clear_config([:instance, :max_remote_account_fields]) describe "handle_incoming" do test "it ignores an incoming notice if we already have it" do @@ -1351,9 +1351,8 @@ test "it accepts Move activities" do end describe "`handle_incoming/2`, Mastodon format `replies` handling" do - clear_config([:activitypub, :note_replies_output_limit], 5) - - clear_config([:instance, :federation_incoming_replies_max_depth]) + setup do: clear_config([:activitypub, :note_replies_output_limit], 5) + setup do: clear_config([:instance, :federation_incoming_replies_max_depth]) setup do data = @@ -1392,9 +1391,8 @@ test "does NOT schedule background fetching of `replies` beyond max thread depth end describe "`handle_incoming/2`, Pleroma format `replies` handling" do - clear_config([:activitypub, :note_replies_output_limit], 5) - - clear_config([:instance, :federation_incoming_replies_max_depth]) + setup do: clear_config([:activitypub, :note_replies_output_limit], 5) + setup do: clear_config([:instance, :federation_incoming_replies_max_depth]) setup do user = insert(:user) @@ -1878,7 +1876,7 @@ test "returns fixed object" do end describe "fix_in_reply_to/2" do - clear_config([:instance, :federation_incoming_replies_max_depth]) + setup do: clear_config([:instance, :federation_incoming_replies_max_depth]) setup do data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) @@ -2141,7 +2139,7 @@ test "returns object with emoji when object contains map tag" do end describe "set_replies/1" do - clear_config([:activitypub, :note_replies_output_limit], 2) + setup do: clear_config([:activitypub, :note_replies_output_limit], 2) test "returns unmodified object if activity doesn't have self-replies" do data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) diff --git a/test/web/activity_pub/views/object_view_test.exs b/test/web/activity_pub/views/object_view_test.exs index 7dda20ec3..de5ffc5b3 100644 --- a/test/web/activity_pub/views/object_view_test.exs +++ b/test/web/activity_pub/views/object_view_test.exs @@ -37,7 +37,7 @@ test "renders a note activity" do end describe "note activity's `replies` collection rendering" do - clear_config([:activitypub, :note_replies_output_limit], 5) + setup do: clear_config([:activitypub, :note_replies_output_limit], 5) test "renders `replies` collection for a note activity" do user = insert(:user) diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 5f3064941..0a902585d 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -43,7 +43,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "with [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage], true) + setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true) test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope", %{admin: admin} do @@ -91,7 +91,7 @@ test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or bro end describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do - clear_config([:auth, :enforce_oauth_admin_scope_usage], false) + setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false) test "GET /api/pleroma/admin/users/:nickname requires " <> "read:accounts or admin:read:accounts or broader scope", @@ -577,8 +577,8 @@ test "/:right DELETE, can remove from a permission group (multiple)", %{ end describe "POST /api/pleroma/admin/email_invite, with valid config" do - clear_config([:instance, :registrations_open], false) - clear_config([:instance, :invites_enabled], true) + setup do: clear_config([:instance, :registrations_open], false) + setup do: clear_config([:instance, :invites_enabled], true) test "sends invitation and returns 204", %{admin: admin, conn: conn} do recipient_email = "foo@bar.com" @@ -629,8 +629,8 @@ test "it returns 403 if requested by a non-admin" do end describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do - clear_config([:instance, :registrations_open]) - clear_config([:instance, :invites_enabled]) + setup do: clear_config([:instance, :registrations_open]) + setup do: clear_config([:instance, :invites_enabled]) test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do Config.put([:instance, :registrations_open], false) @@ -1879,7 +1879,7 @@ test "returns 404 when the status does not exist", %{conn: conn} do end describe "GET /api/pleroma/admin/config" do - clear_config(:configurable_from_database, true) + setup do: clear_config(:configurable_from_database, true) test "when configuration from database is off", %{conn: conn} do Config.put(:configurable_from_database, false) @@ -2030,7 +2030,7 @@ test "POST /api/pleroma/admin/config error", %{conn: conn} do end) end - clear_config(:configurable_from_database, true) + setup do: clear_config(:configurable_from_database, true) @tag capture_log: true test "create new config setting in db", %{conn: conn} do @@ -3039,7 +3039,7 @@ test "proxy tuple ip", %{conn: conn} do end describe "GET /api/pleroma/admin/restart" do - clear_config(:configurable_from_database, true) + setup do: clear_config(:configurable_from_database, true) test "pleroma restarts", %{conn: conn} do capture_log(fn -> diff --git a/test/web/chat_channel_test.exs b/test/web/chat_channel_test.exs index 68c24a9f9..f18f3a212 100644 --- a/test/web/chat_channel_test.exs +++ b/test/web/chat_channel_test.exs @@ -21,7 +21,7 @@ test "it broadcasts a message", %{socket: socket} do end describe "message lengths" do - clear_config([:instance, :chat_limit]) + setup do: clear_config([:instance, :chat_limit]) test "it ignores messages of length zero", %{socket: socket} do push(socket, "new_msg", %{"text" => ""}) diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index b80523160..0da0bd2e2 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -17,9 +17,9 @@ defmodule Pleroma.Web.CommonAPITest do require Pleroma.Constants - clear_config([:instance, :safe_dm_mentions]) - clear_config([:instance, :limit]) - clear_config([:instance, :max_pinned_statuses]) + setup do: clear_config([:instance, :safe_dm_mentions]) + setup do: clear_config([:instance, :limit]) + setup do: clear_config([:instance, :max_pinned_statuses]) test "when replying to a conversation / participation, it will set the correct context id even if no explicit reply_to is given" do user = insert(:user) diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs index 2b321d263..da844c24c 100644 --- a/test/web/federator_test.exs +++ b/test/web/federator_test.exs @@ -21,11 +21,10 @@ defmodule Pleroma.Web.FederatorTest do :ok end - clear_config_all([:instance, :federating], true) - - clear_config([:instance, :allow_relay]) - clear_config([:instance, :rewrite_policy]) - clear_config([:mrf_keyword]) + setup_all do: clear_config([:instance, :federating], true) + setup do: clear_config([:instance, :allow_relay]) + setup do: clear_config([:instance, :rewrite_policy]) + setup do: clear_config([:mrf_keyword]) describe "Publish an activity" do setup do diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs index 5950605e8..1ec39ec5d 100644 --- a/test/web/feed/tag_controller_test.exs +++ b/test/web/feed/tag_controller_test.exs @@ -10,7 +10,7 @@ defmodule Pleroma.Web.Feed.TagControllerTest do alias Pleroma.Web.Feed.FeedView - clear_config([:feed]) + setup do: clear_config([:feed]) test "gets a feed (ATOM)", %{conn: conn} do Pleroma.Config.put( diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs index 49cfecde3..3e52eb42b 100644 --- a/test/web/feed/user_controller_test.exs +++ b/test/web/feed/user_controller_test.exs @@ -12,10 +12,10 @@ defmodule Pleroma.Web.Feed.UserControllerTest do alias Pleroma.Object alias Pleroma.User - clear_config([:instance, :federating], true) + setup do: clear_config([:instance, :federating], true) describe "feed" do - clear_config([:feed]) + setup do: clear_config([:feed]) test "gets a feed", %{conn: conn} do Config.put( diff --git a/test/web/instances/instance_test.exs b/test/web/instances/instance_test.exs index ab8e5643b..e463200ca 100644 --- a/test/web/instances/instance_test.exs +++ b/test/web/instances/instance_test.exs @@ -10,7 +10,7 @@ defmodule Pleroma.Instances.InstanceTest do import Pleroma.Factory - clear_config_all([:instance, :federation_reachability_timeout_days], 1) + setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1) describe "set_reachable/1" do test "clears `unreachable_since` of existing matching Instance record having non-nil `unreachable_since`" do diff --git a/test/web/instances/instances_test.exs b/test/web/instances/instances_test.exs index 1d83c1a1c..d2618025c 100644 --- a/test/web/instances/instances_test.exs +++ b/test/web/instances/instances_test.exs @@ -7,7 +7,7 @@ defmodule Pleroma.InstancesTest do use Pleroma.DataCase - clear_config_all([:instance, :federation_reachability_timeout_days], 1) + setup_all do: clear_config([:instance, :federation_reachability_timeout_days], 1) describe "reachable?/1" do test "returns `true` for host / url with unknown reachability status" do diff --git a/test/web/masto_fe_controller_test.exs b/test/web/masto_fe_controller_test.exs index 9a2d76e0b..1d107d56c 100644 --- a/test/web/masto_fe_controller_test.exs +++ b/test/web/masto_fe_controller_test.exs @@ -10,7 +10,7 @@ defmodule Pleroma.Web.MastodonAPI.MastoFEController do import Pleroma.Factory - clear_config([:instance, :public]) + setup do: clear_config([:instance, :public]) test "put settings", %{conn: conn} do user = insert(:user) diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs index cba68859e..43538cb17 100644 --- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs +++ b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs @@ -9,7 +9,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do use Pleroma.Web.ConnCase import Pleroma.Factory - clear_config([:instance, :max_account_fields]) + + setup do: clear_config([:instance, :max_account_fields]) describe "updating credentials" do setup do: oauth_access(["write:accounts"]) diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index 59ad0a596..a9fa0ce48 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -16,7 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do import Pleroma.Factory describe "account fetching" do - clear_config([:instance, :limit_to_local_content]) + setup do: clear_config([:instance, :limit_to_local_content]) test "works by id" do user = insert(:user) @@ -150,13 +150,9 @@ defp local_and_remote_users do describe "user fetching with restrict unauthenticated profiles for local and remote" do setup do: local_and_remote_users() - clear_config([:restrict_unauthenticated, :profiles, :local]) do - Config.put([:restrict_unauthenticated, :profiles, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) - clear_config([:restrict_unauthenticated, :profiles, :remote]) do - Config.put([:restrict_unauthenticated, :profiles, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}") @@ -186,9 +182,7 @@ test "if user is authenticated", %{local: local, remote: remote} do describe "user fetching with restrict unauthenticated profiles for local" do setup do: local_and_remote_users() - clear_config([:restrict_unauthenticated, :profiles, :local]) do - Config.put([:restrict_unauthenticated, :profiles, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}") @@ -215,9 +209,7 @@ test "if user is authenticated", %{local: local, remote: remote} do describe "user fetching with restrict unauthenticated profiles for remote" do setup do: local_and_remote_users() - clear_config([:restrict_unauthenticated, :profiles, :remote]) do - Config.put([:restrict_unauthenticated, :profiles, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}") @@ -405,13 +397,9 @@ defp local_and_remote_activities(%{local: local, remote: remote}) do setup do: local_and_remote_users() setup :local_and_remote_activities - clear_config([:restrict_unauthenticated, :profiles, :local]) do - Config.put([:restrict_unauthenticated, :profiles, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) - clear_config([:restrict_unauthenticated, :profiles, :remote]) do - Config.put([:restrict_unauthenticated, :profiles, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") @@ -442,9 +430,7 @@ test "if user is authenticated", %{local: local, remote: remote} do setup do: local_and_remote_users() setup :local_and_remote_activities - clear_config([:restrict_unauthenticated, :profiles, :local]) do - Config.put([:restrict_unauthenticated, :profiles, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") @@ -472,9 +458,7 @@ test "if user is authenticated", %{local: local, remote: remote} do setup do: local_and_remote_users() setup :local_and_remote_activities - clear_config([:restrict_unauthenticated, :profiles, :remote]) do - Config.put([:restrict_unauthenticated, :profiles, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") @@ -806,7 +790,7 @@ test "blocking / unblocking a user" do [valid_params: valid_params] end - clear_config([:instance, :account_activation_required]) + setup do: clear_config([:instance, :account_activation_required]) test "Account registration via Application", %{conn: conn} do conn = @@ -904,7 +888,7 @@ test "returns bad_request if missing required params", %{ end) end - clear_config([:instance, :account_activation_required]) + setup do: clear_config([:instance, :account_activation_required]) test "returns bad_request if missing email params when :account_activation_required is enabled", %{conn: conn, valid_params: valid_params} do @@ -961,7 +945,7 @@ test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_ end describe "create account by app / rate limit" do - clear_config([:rate_limit, :app_account_creation], {10_000, 2}) + setup do: clear_config([:rate_limit, :app_account_creation], {10_000, 2}) test "respects rate limit setting", %{conn: conn} do app_token = insert(:oauth_token, user: nil) diff --git a/test/web/mastodon_api/controllers/media_controller_test.exs b/test/web/mastodon_api/controllers/media_controller_test.exs index 203fa73b0..6ac4cf63b 100644 --- a/test/web/mastodon_api/controllers/media_controller_test.exs +++ b/test/web/mastodon_api/controllers/media_controller_test.exs @@ -22,8 +22,8 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do [image: image] end - clear_config([:media_proxy]) - clear_config([Pleroma.Upload]) + setup do: clear_config([:media_proxy]) + setup do: clear_config([Pleroma.Upload]) test "returns uploaded image", %{conn: conn, image: image} do desc = "Description of the image" diff --git a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs index 3cd08c189..f86274d57 100644 --- a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs +++ b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs @@ -11,7 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do import Pleroma.Factory import Ecto.Query - clear_config([ScheduledActivity, :enabled]) + setup do: clear_config([ScheduledActivity, :enabled]) test "shows scheduled activities" do %{user: user, conn: conn} = oauth_access(["read:statuses"]) diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs index beb547780..d59974d50 100644 --- a/test/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/web/mastodon_api/controllers/status_controller_test.exs @@ -19,9 +19,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do import Pleroma.Factory - clear_config([:instance, :federating]) - clear_config([:instance, :allow_relay]) - clear_config([:rich_media, :enabled]) + setup do: clear_config([:instance, :federating]) + setup do: clear_config([:instance, :allow_relay]) + setup do: clear_config([:rich_media, :enabled]) describe "posting statuses" do setup do: oauth_access(["write:statuses"]) @@ -485,13 +485,9 @@ defp local_and_remote_activities do describe "status with restrict unauthenticated activities for local and remote" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :activities, :local]) do - Config.put([:restrict_unauthenticated, :activities, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) - clear_config([:restrict_unauthenticated, :activities, :remote]) do - Config.put([:restrict_unauthenticated, :activities, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/statuses/#{local.id}") @@ -520,9 +516,7 @@ test "if user is authenticated", %{local: local, remote: remote} do describe "status with restrict unauthenticated activities for local" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :activities, :local]) do - Config.put([:restrict_unauthenticated, :activities, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/statuses/#{local.id}") @@ -548,9 +542,7 @@ test "if user is authenticated", %{local: local, remote: remote} do describe "status with restrict unauthenticated activities for remote" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :activities, :remote]) do - Config.put([:restrict_unauthenticated, :activities, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/statuses/#{local.id}") @@ -614,13 +606,9 @@ test "get statuses by IDs" do describe "getting statuses by ids with restricted unauthenticated for local and remote" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :activities, :local]) do - Config.put([:restrict_unauthenticated, :activities, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) - clear_config([:restrict_unauthenticated, :activities, :remote]) do - Config.put([:restrict_unauthenticated, :activities, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) @@ -640,9 +628,7 @@ test "if user is authenticated", %{local: local, remote: remote} do describe "getting statuses by ids with restricted unauthenticated for local" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :activities, :local]) do - Config.put([:restrict_unauthenticated, :activities, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) @@ -663,9 +649,7 @@ test "if user is authenticated", %{local: local, remote: remote} do describe "getting statuses by ids with restricted unauthenticated for remote" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :activities, :remote]) do - Config.put([:restrict_unauthenticated, :activities, :remote], true) - end + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/statuses", %{ids: [local.id, remote.id]}) @@ -908,7 +892,7 @@ test "returns 404 error for a wrong id", %{conn: conn} do %{activity: activity} end - clear_config([:instance, :max_pinned_statuses], 1) + setup do: clear_config([:instance, :max_pinned_statuses], 1) test "pin status", %{conn: conn, user: user, activity: activity} do id_str = to_string(activity.id) diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs index a15c759d4..6fedb4223 100644 --- a/test/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs @@ -100,13 +100,9 @@ defp local_and_remote_activities do describe "public with restrict unauthenticated timeline for local and federated timelines" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :timelines, :local]) do - Config.put([:restrict_unauthenticated, :timelines, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true) - clear_config([:restrict_unauthenticated, :timelines, :federated]) do - Config.put([:restrict_unauthenticated, :timelines, :federated], true) - end + setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true) test "if user is unauthenticated", %{conn: conn} do res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) @@ -136,9 +132,7 @@ test "if user is authenticated" do describe "public with restrict unauthenticated timeline for local" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :timelines, :local]) do - Config.put([:restrict_unauthenticated, :timelines, :local], true) - end + setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true) test "if user is unauthenticated", %{conn: conn} do res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) @@ -165,9 +159,7 @@ test "if user is authenticated", %{conn: _conn} do describe "public with restrict unauthenticated timeline for remote" do setup do: local_and_remote_activities() - clear_config([:restrict_unauthenticated, :timelines, :federated]) do - Config.put([:restrict_unauthenticated, :timelines, :federated], true) - end + setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true) test "if user is unauthenticated", %{conn: conn} do res_conn = get(conn, "/api/v1/timelines/public", %{"local" => "true"}) diff --git a/test/web/media_proxy/media_proxy_controller_test.exs b/test/web/media_proxy/media_proxy_controller_test.exs index 7ac7e4af1..da79d38a5 100644 --- a/test/web/media_proxy/media_proxy_controller_test.exs +++ b/test/web/media_proxy/media_proxy_controller_test.exs @@ -7,8 +7,8 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do import Mock alias Pleroma.Config - clear_config(:media_proxy) - clear_config([Pleroma.Web.Endpoint, :secret_key_base]) + setup do: clear_config(:media_proxy) + setup do: clear_config([Pleroma.Web.Endpoint, :secret_key_base]) test "it returns 404 when MediaProxy disabled", %{conn: conn} do Config.put([:media_proxy, :enabled], false) diff --git a/test/web/media_proxy/media_proxy_test.exs b/test/web/media_proxy/media_proxy_test.exs index 8f5fcf2eb..69c2d5dae 100644 --- a/test/web/media_proxy/media_proxy_test.exs +++ b/test/web/media_proxy/media_proxy_test.exs @@ -8,8 +8,8 @@ defmodule Pleroma.Web.MediaProxyTest do import Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy.MediaProxyController - clear_config([:media_proxy, :enabled]) - clear_config(Pleroma.Upload) + setup do: clear_config([:media_proxy, :enabled]) + setup do: clear_config(Pleroma.Upload) describe "when enabled" do setup do diff --git a/test/web/metadata/opengraph_test.exs b/test/web/metadata/opengraph_test.exs index 9d7c009eb..218540e6c 100644 --- a/test/web/metadata/opengraph_test.exs +++ b/test/web/metadata/opengraph_test.exs @@ -7,7 +7,7 @@ defmodule Pleroma.Web.Metadata.Providers.OpenGraphTest do import Pleroma.Factory alias Pleroma.Web.Metadata.Providers.OpenGraph - clear_config([Pleroma.Web.Metadata, :unfurl_nsfw]) + setup do: clear_config([Pleroma.Web.Metadata, :unfurl_nsfw]) test "it renders all supported types of attachments and skips unknown types" do user = insert(:user) diff --git a/test/web/metadata/twitter_card_test.exs b/test/web/metadata/twitter_card_test.exs index 3d75d1ed5..9e9c6853a 100644 --- a/test/web/metadata/twitter_card_test.exs +++ b/test/web/metadata/twitter_card_test.exs @@ -13,7 +13,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do alias Pleroma.Web.Metadata.Utils alias Pleroma.Web.Router - clear_config([Pleroma.Web.Metadata, :unfurl_nsfw]) + setup do: clear_config([Pleroma.Web.Metadata, :unfurl_nsfw]) test "it renders twitter card for user info" do user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994") diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index ee10ad5db..43f322606 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -7,8 +7,8 @@ defmodule Pleroma.Web.NodeInfoTest do import Pleroma.Factory - clear_config([:mrf_simple]) - clear_config(:instance) + setup do: clear_config([:mrf_simple]) + setup do: clear_config(:instance) test "GET /.well-known/nodeinfo", %{conn: conn} do links = @@ -105,7 +105,7 @@ test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do end describe "`metadata/federation/enabled`" do - clear_config([:instance, :federating]) + setup do: clear_config([:instance, :federating]) test "it shows if federation is enabled/disabled", %{conn: conn} do Pleroma.Config.put([:instance, :federating], true) diff --git a/test/web/oauth/ldap_authorization_test.exs b/test/web/oauth/ldap_authorization_test.exs index b348281c5..a8fe8a841 100644 --- a/test/web/oauth/ldap_authorization_test.exs +++ b/test/web/oauth/ldap_authorization_test.exs @@ -12,9 +12,9 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do @skip if !Code.ensure_loaded?(:eldap), do: :skip - clear_config_all([:ldap, :enabled], true) + setup_all do: clear_config([:ldap, :enabled], true) - clear_config_all(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.LDAPAuthenticator) + setup_all do: clear_config(Pleroma.Web.Auth.Authenticator, Pleroma.Web.Auth.LDAPAuthenticator) @tag @skip test "authorizes the existing user using LDAP credentials" do diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs index 592612ddf..0b0972b17 100644 --- a/test/web/oauth/oauth_controller_test.exs +++ b/test/web/oauth/oauth_controller_test.exs @@ -17,8 +17,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do key: "_test", signing_salt: "cooldude" ] - - clear_config([:instance, :account_activation_required]) + setup do: clear_config([:instance, :account_activation_required]) describe "in OAuth consumer mode, " do setup do @@ -31,7 +30,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do ] end - clear_config([:auth, :oauth_consumer_strategies], ~w(twitter facebook)) + setup do: clear_config([:auth, :oauth_consumer_strategies], ~w(twitter facebook)) test "GET /oauth/authorize renders auth forms, including OAuth consumer form", %{ app: app, @@ -939,7 +938,7 @@ test "rejects an invalid authorization code" do end describe "POST /oauth/token - refresh token" do - clear_config([:oauth2, :issue_new_refresh_token]) + setup do: clear_config([:oauth2, :issue_new_refresh_token]) test "issues a new access token with keep fresh token" do Pleroma.Config.put([:oauth2, :issue_new_refresh_token], true) diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 6a3dcf2cd..6787b414b 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -17,7 +17,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do :ok end - clear_config([:instance, :federating], true) + setup do: clear_config([:instance, :federating], true) # Note: see ActivityPubControllerTest for JSON format tests describe "GET /objects/:uuid (text/html)" do diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/web/pleroma_api/controllers/account_controller_test.exs index bc359707d..2aa87ac30 100644 --- a/test/web/pleroma_api/controllers/account_controller_test.exs +++ b/test/web/pleroma_api/controllers/account_controller_test.exs @@ -27,7 +27,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do [user: user] end - clear_config([:instance, :account_activation_required], true) + setup do: clear_config([:instance, :account_activation_required], true) test "resend account confirmation email", %{conn: conn, user: user} do conn diff --git a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs index 146f3f4fe..435fb6592 100644 --- a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs @@ -12,8 +12,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do Pleroma.Config.get!([:instance, :static_dir]), "emoji" ) - - clear_config([:auth, :enforce_oauth_admin_scope_usage], false) + setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false) test "shared & non-shared pack information in list_packs is ok" do conn = build_conn() diff --git a/test/web/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs index 13edc4359..2f8aadadc 100644 --- a/test/web/plugs/federating_plug_test.exs +++ b/test/web/plugs/federating_plug_test.exs @@ -5,7 +5,7 @@ defmodule Pleroma.Web.FederatingPlugTest do use Pleroma.Web.ConnCase - clear_config([:instance, :federating]) + setup do: clear_config([:instance, :federating]) test "returns and halt the conn when federating is disabled" do Pleroma.Config.put([:instance, :federating], false) diff --git a/test/web/rich_media/helpers_test.exs b/test/web/rich_media/helpers_test.exs index 8237802a7..aa0c5c830 100644 --- a/test/web/rich_media/helpers_test.exs +++ b/test/web/rich_media/helpers_test.exs @@ -19,7 +19,7 @@ defmodule Pleroma.Web.RichMedia.HelpersTest do :ok end - clear_config([:rich_media, :enabled]) + setup do: clear_config([:rich_media, :enabled]) test "refuses to crawl incomplete URLs" do user = insert(:user) diff --git a/test/web/static_fe/static_fe_controller_test.exs b/test/web/static_fe/static_fe_controller_test.exs index aabbedb17..430683ea0 100644 --- a/test/web/static_fe/static_fe_controller_test.exs +++ b/test/web/static_fe/static_fe_controller_test.exs @@ -8,9 +8,8 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do import Pleroma.Factory - clear_config_all([:static_fe, :enabled], true) - - clear_config([:instance, :federating], true) + setup_all do: clear_config([:static_fe, :enabled], true) + setup do: clear_config([:instance, :federating], true) setup %{conn: conn} do conn = put_req_header(conn, "accept", "text/html") diff --git a/test/web/streamer/streamer_test.exs b/test/web/streamer/streamer_test.exs index 339f99bbf..a5d6e8ecf 100644 --- a/test/web/streamer/streamer_test.exs +++ b/test/web/streamer/streamer_test.exs @@ -19,8 +19,7 @@ defmodule Pleroma.Web.StreamerTest do @streamer_timeout 150 @streamer_start_wait 10 - - clear_config([:instance, :skip_thread_containment]) + setup do: clear_config([:instance, :skip_thread_containment]) describe "user streams" do setup do diff --git a/test/web/twitter_api/remote_follow_controller_test.exs b/test/web/twitter_api/remote_follow_controller_test.exs index 5c6087527..5ff8694a8 100644 --- a/test/web/twitter_api/remote_follow_controller_test.exs +++ b/test/web/twitter_api/remote_follow_controller_test.exs @@ -17,11 +17,10 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do :ok end - clear_config_all([:instance, :federating], true) - - clear_config([:instance]) - clear_config([:frontend_configurations, :pleroma_fe]) - clear_config([:user, :deny_follow_blocked]) + setup_all do: clear_config([:instance, :federating], true) + setup do: clear_config([:instance]) + setup do: clear_config([:frontend_configurations, :pleroma_fe]) + setup do: clear_config([:user, :deny_follow_blocked]) describe "GET /ostatus_subscribe - remote_follow/2" do test "adds status to pleroma instance if the `acct` is a status", %{conn: conn} do diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 0e787715a..92f9aa0f5 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -117,7 +117,7 @@ test "it registers a new user and parses mentions in the bio" do end describe "register with one time token" do - clear_config([:instance, :registrations_open], false) + setup do: clear_config([:instance, :registrations_open], false) test "returns user on success" do {:ok, invite} = UserInviteToken.create_invite() @@ -182,7 +182,7 @@ test "returns error on expired token" do end describe "registers with date limited token" do - clear_config([:instance, :registrations_open], false) + setup do: clear_config([:instance, :registrations_open], false) setup do data = %{ @@ -242,7 +242,7 @@ test "returns an error on overdue date", %{data: data} do end describe "registers with reusable token" do - clear_config([:instance, :registrations_open], false) + setup do: clear_config([:instance, :registrations_open], false) test "returns user on success, after him registration fails" do {:ok, invite} = UserInviteToken.create_invite(%{max_use: 100}) @@ -286,7 +286,7 @@ test "returns user on success, after him registration fails" do end describe "registers with reusable date limited token" do - clear_config([:instance, :registrations_open], false) + setup do: clear_config([:instance, :registrations_open], false) test "returns user on success" do {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100}) diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs index 71ecd1aa7..30e54bebd 100644 --- a/test/web/twitter_api/util_controller_test.exs +++ b/test/web/twitter_api/util_controller_test.exs @@ -18,8 +18,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do :ok end - clear_config([:instance]) - clear_config([:frontend_configurations, :pleroma_fe]) + setup do: clear_config([:instance]) + setup do: clear_config([:frontend_configurations, :pleroma_fe]) describe "POST /api/pleroma/follow_import" do setup do: oauth_access(["follow"]) @@ -318,7 +318,7 @@ test "returns json with custom emoji with tags", %{conn: conn} do end describe "GET /api/pleroma/healthcheck" do - clear_config([:instance, :healthcheck]) + setup do: clear_config([:instance, :healthcheck]) test "returns 503 when healthcheck disabled", %{conn: conn} do Config.put([:instance, :healthcheck], false) @@ -427,7 +427,7 @@ test "it returns version in json format", %{conn: conn} do end describe "POST /main/ostatus - remote_subscribe/2" do - clear_config([:instance, :federating], true) + setup do: clear_config([:instance, :federating], true) test "renders subscribe form", %{conn: conn} do user = insert(:user) diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/web/web_finger/web_finger_controller_test.exs index fcf14dc1e..0023f1e81 100644 --- a/test/web/web_finger/web_finger_controller_test.exs +++ b/test/web/web_finger/web_finger_controller_test.exs @@ -14,7 +14,7 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do :ok end - clear_config_all([:instance, :federating], true) + setup_all do: clear_config([:instance, :federating], true) test "GET host-meta" do response = diff --git a/test/workers/cron/clear_oauth_token_worker_test.exs b/test/workers/cron/clear_oauth_token_worker_test.exs index f056b1a3e..df82dc75d 100644 --- a/test/workers/cron/clear_oauth_token_worker_test.exs +++ b/test/workers/cron/clear_oauth_token_worker_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.Workers.Cron.ClearOauthTokenWorkerTest do import Pleroma.Factory alias Pleroma.Workers.Cron.ClearOauthTokenWorker - clear_config([:oauth2, :clean_expired_tokens]) + setup do: clear_config([:oauth2, :clean_expired_tokens]) test "deletes expired tokens" do insert(:oauth_token, diff --git a/test/workers/cron/digest_emails_worker_test.exs b/test/workers/cron/digest_emails_worker_test.exs index 5d65b9fef..0a63bf4e0 100644 --- a/test/workers/cron/digest_emails_worker_test.exs +++ b/test/workers/cron/digest_emails_worker_test.exs @@ -11,7 +11,7 @@ defmodule Pleroma.Workers.Cron.DigestEmailsWorkerTest do alias Pleroma.User alias Pleroma.Web.CommonAPI - clear_config([:email_notifications, :digest]) + setup do: clear_config([:email_notifications, :digest]) setup do Pleroma.Config.put([:email_notifications, :digest], %{ diff --git a/test/workers/cron/purge_expired_activities_worker_test.exs b/test/workers/cron/purge_expired_activities_worker_test.exs index 56c5aa409..5864f9e5f 100644 --- a/test/workers/cron/purge_expired_activities_worker_test.exs +++ b/test/workers/cron/purge_expired_activities_worker_test.exs @@ -11,7 +11,7 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorkerTest do import Pleroma.Factory import ExUnit.CaptureLog - clear_config([ActivityExpiration, :enabled]) + setup do: clear_config([ActivityExpiration, :enabled]) test "deletes an expiration activity" do Pleroma.Config.put([ActivityExpiration, :enabled], true) diff --git a/test/workers/scheduled_activity_worker_test.exs b/test/workers/scheduled_activity_worker_test.exs index ab9f9c125..b312d975b 100644 --- a/test/workers/scheduled_activity_worker_test.exs +++ b/test/workers/scheduled_activity_worker_test.exs @@ -11,7 +11,7 @@ defmodule Pleroma.Workers.ScheduledActivityWorkerTest do import Pleroma.Factory import ExUnit.CaptureLog - clear_config([ScheduledActivity, :enabled]) + setup do: clear_config([ScheduledActivity, :enabled]) test "creates a status from the scheduled activity" do Pleroma.Config.put([ScheduledActivity, :enabled], true) From 981e015f1b68c7cf807b0ddbf3948809f11b7fff Mon Sep 17 00:00:00 2001 From: rinpatch Date: Sun, 22 Mar 2020 17:10:37 +0300 Subject: [PATCH 14/17] Mastodon API Account view: Remove an outdated hack The hack with caching the follow relationship was introduced when we still were storing it inside the follow activity, resulting in slow queries. Now we store follow state in `FollowRelationship` table, so this is no longer necessary. --- lib/pleroma/user.ex | 18 ------------------ lib/pleroma/web/activity_pub/activity_pub.ex | 3 +-- lib/pleroma/web/activity_pub/utils.ex | 5 +---- .../web/mastodon_api/views/account_view.ex | 13 +++---------- 4 files changed, 5 insertions(+), 34 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 8693c0b80..12c2ad815 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -292,24 +292,6 @@ def ap_followers(%User{} = user), do: "#{ap_id(user)}/followers" def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa def ap_following(%User{} = user), do: "#{ap_id(user)}/following" - def follow_state(%User{} = user, %User{} = target) do - case Utils.fetch_latest_follow(user, target) do - %{data: %{"state" => state}} -> state - # Ideally this would be nil, but then Cachex does not commit the value - _ -> false - end - end - - def get_cached_follow_state(user, target) do - key = "follow_state:#{user.ap_id}|#{target.ap_id}" - Cachex.fetch!(:user_cache, key, fn _ -> {:commit, follow_state(user, target)} end) - end - - @spec set_follow_state_cache(String.t(), String.t(), String.t()) :: {:ok | :error, boolean()} - def set_follow_state_cache(user_ap_id, target_ap_id, state) do - Cachex.put(:user_cache, "follow_state:#{user_ap_id}|#{target_ap_id}", state) - end - @spec restrict_deactivated(Ecto.Query.t()) :: Ecto.Query.t() def restrict_deactivated(query) do from(u in query, where: u.deactivated != ^true) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index d9f74b6a4..30e282840 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -503,8 +503,7 @@ def follow(follower, followed, activity_id \\ nil, local \\ true) do defp do_follow(follower, followed, activity_id, local) do with data <- make_follow_data(follower, followed, activity_id), {:ok, activity} <- insert(data, local), - :ok <- maybe_federate(activity), - _ <- User.set_follow_state_cache(follower.ap_id, followed.ap_id, activity.data["state"]) do + :ok <- maybe_federate(activity) do {:ok, activity} else {:error, error} -> Repo.rollback(error) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 15dd2ed45..c65bbed67 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -440,22 +440,19 @@ def update_follow_state_for_all( |> update(set: [data: fragment("jsonb_set(data, '{state}', ?)", ^state)]) |> Repo.update_all([]) - User.set_follow_state_cache(actor, object, state) - activity = Activity.get_by_id(activity.id) {:ok, activity} end def update_follow_state( - %Activity{data: %{"actor" => actor, "object" => object}} = activity, + %Activity{} = activity, state ) do new_data = Map.put(activity.data, "state", state) changeset = Changeset.change(activity, data: new_data) with {:ok, activity} <- Repo.update(changeset) do - User.set_follow_state_cache(actor, object, state) {:ok, activity} end end diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 341dc2c91..4ebce73b4 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -36,25 +36,18 @@ def render("relationship.json", %{user: nil, target: _target}) do end def render("relationship.json", %{user: %User{} = user, target: %User{} = target}) do - follow_state = User.get_cached_follow_state(user, target) - - requested = - if follow_state && !User.following?(user, target) do - follow_state == "pending" - else - false - end + follow_state = User.get_follow_state(user, target) %{ id: to_string(target.id), - following: User.following?(user, target), + following: follow_state == "accept", followed_by: User.following?(target, user), blocking: User.blocks_user?(user, target), blocked_by: User.blocks_user?(target, user), muting: User.mutes?(user, target), muting_notifications: User.muted_notifications?(user, target), subscribing: User.subscribed_to?(user, target), - requested: requested, + requested: follow_state == "pending", domain_blocking: User.blocks_domain?(user, target), showing_reblogs: User.showing_reblogs?(user, target), endorsed: false From 15be6ba9c200b2a4ae153d26876be1b5cbb6357e Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 22 Mar 2020 16:38:12 +0100 Subject: [PATCH 15/17] AccountView: fix for other forms of
in bio Closes: https://git.pleroma.social/pleroma/pleroma/issues/1643 --- lib/pleroma/web/mastodon_api/views/account_view.ex | 2 +- .../account_controller/update_credentials_test.exs | 4 ++-- test/web/mastodon_api/views/account_view_test.exs | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 4ebce73b4..2bf711386 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -115,7 +115,7 @@ defp do_render("show.json", %{user: user} = opts) do fields: user.fields, bot: bot, source: %{ - note: Pleroma.HTML.strip_tags((user.bio || "") |> String.replace("
", "\n")), + note: (user.bio || "") |> String.replace(~r(
), "\n") |> Pleroma.HTML.strip_tags(), sensitive: false, fields: user.raw_fields, pleroma: %{ diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs index 43538cb17..51cebe567 100644 --- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs +++ b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs @@ -76,7 +76,7 @@ test "updates the user's bio", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{ - "note" => "I drink #cofe with @#{user2.nickname}" + "note" => "I drink #cofe with @#{user2.nickname}\n\nsuya.." }) assert user_data = json_response(conn, 200) @@ -84,7 +84,7 @@ test "updates the user's bio", %{conn: conn} do assert user_data["note"] == ~s(I drink #cofe with @#{user2.nickname}) + }" class="u-url mention" href="#{user2.ap_id}" rel="ugc">@#{user2.nickname}

suya..) end test "updates the user's locking status", %{conn: conn} do diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs index d60ed7b64..983886c6b 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -32,7 +32,8 @@ test "Represent a user account" do background: background_image, nickname: "shp@shitposter.club", name: ":karjalanpiirakka: shp", - bio: "valid html", + bio: + "valid html. a
b
c
d
f", inserted_at: ~N[2017-08-15 15:47:06.597036] }) @@ -46,7 +47,7 @@ test "Represent a user account" do followers_count: 3, following_count: 0, statuses_count: 5, - note: "valid html", + note: "valid html. a
b
c
d
f", url: user.ap_id, avatar: "http://localhost:4001/images/avi.png", avatar_static: "http://localhost:4001/images/avi.png", @@ -63,7 +64,7 @@ test "Represent a user account" do fields: [], bot: false, source: %{ - note: "valid html", + note: "valid html. a\nb\nc\nd\nf", sensitive: false, pleroma: %{ actor_type: "Person", From 5a34dca8eda46479a3459b60c623d6fa94fc662b Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 23 Mar 2020 14:03:31 +0400 Subject: [PATCH 16/17] Add emoji support in statuses in staticfe --- lib/pleroma/web/static_fe/static_fe_controller.ex | 4 +++- priv/static/static/static-fe.css | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/static_fe/static_fe_controller.ex b/lib/pleroma/web/static_fe/static_fe_controller.ex index 7f9464268..7a35238d7 100644 --- a/lib/pleroma/web/static_fe/static_fe_controller.ex +++ b/lib/pleroma/web/static_fe/static_fe_controller.ex @@ -60,7 +60,9 @@ defp represent(%Activity{object: %Object{data: data}} = activity, selected) do content = if data["content"] do - Pleroma.HTML.filter_tags(data["content"]) + data["content"] + |> Pleroma.HTML.filter_tags() + |> Pleroma.Emoji.Formatter.emojify(Map.get(data, "emoji", %{})) else nil end diff --git a/priv/static/static/static-fe.css b/priv/static/static/static-fe.css index 19c56387b..db61ff266 100644 --- a/priv/static/static/static-fe.css +++ b/priv/static/static/static-fe.css @@ -174,3 +174,10 @@ .alert-info { font-weight: 500; font-size: 16px; } + +img.emoji { + width: 32px; + height: 32px; + padding: 0; + vertical-align: middle; +} From d1a9716a988fe9f670033ad46cc9637038fbd1e8 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Tue, 24 Mar 2020 17:38:18 +0400 Subject: [PATCH 17/17] Fix activity deletion --- lib/pleroma/web/activity_pub/activity_pub.ex | 10 ++++++++++ test/web/activity_pub/activity_pub_test.exs | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 30e282840..974231925 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -583,6 +583,16 @@ defp do_delete(%Object{data: %{"id" => id, "actor" => actor}} = object, options) end end + defp do_delete(%Object{data: %{"type" => "Tombstone", "id" => ap_id}}, _) do + activity = + ap_id + |> Activity.Queries.by_object_id() + |> Activity.Queries.by_type("Delete") + |> Repo.one() + + {:ok, activity} + end + @spec block(User.t(), User.t(), String.t() | nil, boolean()) :: {:ok, Activity.t()} | {:error, any()} def block(blocker, blocked, activity_id \\ nil, local \\ true) do diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index a43dd34f0..049b14498 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -1425,6 +1425,12 @@ test "it creates a delete activity and deletes the original object" do assert Repo.get(Object, object.id).data["type"] == "Tombstone" end + test "it doesn't fail when an activity was already deleted" do + {:ok, delete} = insert(:note_activity) |> Object.normalize() |> ActivityPub.delete() + + assert {:ok, ^delete} = delete |> Object.normalize() |> ActivityPub.delete() + end + test "decrements user note count only for public activities" do user = insert(:user, note_count: 10)