From 7829de6da4b2782a4ae2124ff05787d500bbb990 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Mon, 16 Mar 2020 17:26:28 +0300 Subject: [PATCH 1/5] gitlab: create templates for bug reports and release MRs --- .gitlab/issue_templates/Bug.md | 20 ++++++++++++++++++++ .gitlab/merge_request_templates/Release.md | 5 +++++ 2 files changed, 25 insertions(+) create mode 100644 .gitlab/issue_templates/Bug.md create mode 100644 .gitlab/merge_request_templates/Release.md diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md new file mode 100644 index 000000000..66fbc510e --- /dev/null +++ b/.gitlab/issue_templates/Bug.md @@ -0,0 +1,20 @@ + + +### Environment + +* Installation type: + - [ ] OTP + - [ ] From source +* Pleroma version (could be found in the "Version" tab of settings in Pleroma-FE): +* Elixir version (`elixir -v` for from source installations, N/A for OTP): +* Operating system: +* PostgreSQL version (`postgres -V`): + + +### Bug description diff --git a/.gitlab/merge_request_templates/Release.md b/.gitlab/merge_request_templates/Release.md new file mode 100644 index 000000000..237f74e00 --- /dev/null +++ b/.gitlab/merge_request_templates/Release.md @@ -0,0 +1,5 @@ +### Release checklist +* [ ] Bump version in `mix.exs` +* [ ] Compile a changelog +* [ ] Create an MR with an announcement to pleroma.social +* [ ] Tag the release From 8dd01b24d2e64b61992ff9c6895c98f7f7052c6c Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Mon, 16 Mar 2020 11:44:53 -0500 Subject: [PATCH 2/5] 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 3/5] 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 a8c6933ca023d7487910a0f99aed62fa8c2d45e2 Mon Sep 17 00:00:00 2001 From: stwf Date: Thu, 19 Mar 2020 12:25:36 -0400 Subject: [PATCH 4/5] 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 5/5] 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)