From 9272cef500308862d0d86be329bad7f41c66d4ad Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Thu, 28 Jan 2021 14:03:29 -0600 Subject: [PATCH 1/3] Switch to a build of Majic that does not try to fix extensions by default --- mix.exs | 2 +- mix.lock | 2 +- .../pleroma/web/activity_pub/activity_pub_controller_test.exs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.exs b/mix.exs index 489bb5729..50d4b4080 100644 --- a/mix.exs +++ b/mix.exs @@ -194,7 +194,7 @@ defp deps do {:restarter, path: "./restarter"}, {:majic, git: "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", - ref: "4c692e544b28d1f5e543fb8a44be090f8cd96f80"}, + ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"}, {:open_api_spex, git: "https://git.pleroma.social/pleroma/elixir-libraries/open_api_spex.git", ref: "f296ac0924ba3cf79c7a588c4c252889df4c2edd"}, diff --git a/mix.lock b/mix.lock index 840a82555..3e5631c72 100644 --- a/mix.lock +++ b/mix.lock @@ -66,7 +66,7 @@ "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"}, "linkify": {:hex, :linkify, "0.4.1", "f881eb3429ae88010cf736e6fb3eed406c187bcdd544902ec937496636b7c7b3", [:mix], [], "hexpm", "ce98693f54ae9ace59f2f7a8aed3de2ef311381a8ce7794804bd75484c371dda"}, - "majic": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", "4c692e544b28d1f5e543fb8a44be090f8cd96f80", [ref: "4c692e544b28d1f5e543fb8a44be090f8cd96f80"]}, + "majic": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/majic.git", "289cda1b6d0d70ccb2ba508a2b0bd24638db2880", [ref: "289cda1b6d0d70ccb2ba508a2b0bd24638db2880"]}, "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"}, diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index f7417de31..91a3109bb 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -1607,9 +1607,9 @@ test "POST /api/ap/upload_media", %{conn: conn} do desc = "Description of the image" image = %Plug.Upload{ - content_type: "bad/content-type", + content_type: "image/jpeg", path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.png" + filename: "an_image.jpg" } object = From c369d2b93028e4dc11f1f2c4cd7380ee0392ccac Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Fri, 29 Jan 2021 08:41:21 +0300 Subject: [PATCH 2/3] support for with_relationships parameter in /api/v1/mutes and /api/v1/accounts/:id endpoints --- CHANGELOG.md | 3 +- .../API/differences_in_mastoapi_responses.md | 7 + .../api_spec/operations/account_operation.ex | 7 +- .../controllers/account_controller.ex | 15 +- .../controllers/account_controller_test.exs | 134 +++++++++++++++++- 5 files changed, 155 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4f3867a2..b2b7e5671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute. - Admin API: An endpoint to manage frontends. - Streaming API: Add follow relationships updates. -- WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types +- WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types. +- Mastodon API: `/api/v1/accounts/:id` & `/api/v1/mutes` endpoints accept `with_relationships` parameter and return filled `pleroma.relationship` field. ### Fixed diff --git a/docs/development/API/differences_in_mastoapi_responses.md b/docs/development/API/differences_in_mastoapi_responses.md index 84430408b..b532d14ed 100644 --- a/docs/development/API/differences_in_mastoapi_responses.md +++ b/docs/development/API/differences_in_mastoapi_responses.md @@ -54,6 +54,13 @@ The `id` parameter can also be the `nickname` of the user. This only works in th - `/api/v1/accounts/:id` - `/api/v1/accounts/:id/statuses` +Endpoints which accept `with_relationships` parameter: + +- `/api/v1/accounts/:id` +- `/api/v1/accounts/:id/followers` +- `/api/v1/accounts/:id/following` +- `/api/v1/mutes` + Has these additional fields under the `pleroma` object: - `ap_id`: nullable URL string, ActivityPub id of the user diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 80acee2f7..d7e01f55b 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -99,7 +99,10 @@ def show_operation do summary: "Account", operationId: "AccountController.show", description: "View information about a profile.", - parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}], + parameters: [ + %Reference{"$ref": "#/components/parameters/accountIdOrNickname"}, + with_relationships_param() + ], responses: %{ 200 => Operation.response("Account", "application/json", Account), 401 => Operation.response("Error", "application/json", ApiError), @@ -347,7 +350,7 @@ def mutes_operation do operationId: "AccountController.mutes", description: "Accounts the user has muted.", security: [%{"oAuth" => ["follow", "read:mutes"]}], - parameters: pagination_params(), + parameters: [with_relationships_param() | pagination_params()], responses: %{ 200 => Operation.response("Accounts", "application/json", array_of_accounts()) } diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index d277aeca5..7a1e99044 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -269,10 +269,14 @@ def relationships(%{assigns: %{user: user}} = conn, %{id: id}) do def relationships(%{assigns: %{user: _user}} = conn, _), do: json(conn, []) @doc "GET /api/v1/accounts/:id" - def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id}) do + def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id} = params) do with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user), :visible <- User.visible_for(user, for_user) do - render(conn, "show.json", user: user, for: for_user) + render(conn, "show.json", + user: user, + for: for_user, + embed_relationships: embed_relationships?(params) + ) else error -> user_visibility_error(conn, error) end @@ -454,7 +458,12 @@ def mutes(%{assigns: %{user: user}} = conn, params) do conn |> add_link_headers(users) - |> render("index.json", users: users, for: user, as: :user) + |> render("index.json", + users: users, + for: user, + as: :user, + embed_relationships: embed_relationships?(params) + ) end @doc "GET /api/v1/blocks" diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index 1276597a4..e5020feca 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -29,6 +29,45 @@ test "works by id" do |> json_response_and_validate_schema(404) end + test "relationship field" do + %{conn: conn, user: user} = oauth_access(["read"]) + + other_user = insert(:user) + + response = + conn + |> get("/api/v1/accounts/#{other_user.id}") + |> json_response_and_validate_schema(200) + + assert response["id"] == other_user.id + assert response["pleroma"]["relationship"] == %{} + + assert %{"pleroma" => %{"relationship" => %{"following" => false, "followed_by" => false}}} = + conn + |> get("/api/v1/accounts/#{other_user.id}?with_relationships=true") + |> json_response_and_validate_schema(200) + + {:ok, _, %{id: other_id}} = User.follow(user, other_user) + + assert %{ + "id" => ^other_id, + "pleroma" => %{"relationship" => %{"following" => true, "followed_by" => false}} + } = + conn + |> get("/api/v1/accounts/#{other_id}?with_relationships=true") + |> json_response_and_validate_schema(200) + + {:ok, _, _} = User.follow(other_user, user) + + assert %{ + "id" => ^other_id, + "pleroma" => %{"relationship" => %{"following" => true, "followed_by" => true}} + } = + conn + |> get("/api/v1/accounts/#{other_id}?with_relationships=true") + |> json_response_and_validate_schema(200) + end + test "works by nickname" do user = insert(:user) @@ -590,6 +629,45 @@ test "getting followers", %{user: user, conn: conn} do assert [%{"id" => ^user_id}] = json_response_and_validate_schema(conn, 200) end + test "following with relationship", %{conn: conn, user: user} do + other_user = insert(:user) + {:ok, %{id: id}, _} = User.follow(other_user, user) + + assert [ + %{ + "id" => ^id, + "pleroma" => %{ + "relationship" => %{ + "id" => ^id, + "following" => false, + "followed_by" => true + } + } + } + ] = + conn + |> get("/api/v1/accounts/#{user.id}/followers?with_relationships=true") + |> json_response_and_validate_schema(200) + + {:ok, _, _} = User.follow(user, other_user) + + assert [ + %{ + "id" => ^id, + "pleroma" => %{ + "relationship" => %{ + "id" => ^id, + "following" => true, + "followed_by" => true + } + } + } + ] = + conn + |> get("/api/v1/accounts/#{user.id}/followers?with_relationships=true") + |> json_response_and_validate_schema(200) + end + test "getting followers, hide_followers", %{user: user, conn: conn} do other_user = insert(:user, hide_followers: true) {:ok, _user, _other_user} = User.follow(user, other_user) @@ -660,6 +738,24 @@ test "getting following", %{user: user, conn: conn} do assert id == to_string(other_user.id) end + test "following with relationship", %{conn: conn, user: user} do + other_user = insert(:user) + {:ok, user, other_user} = User.follow(user, other_user) + + conn = get(conn, "/api/v1/accounts/#{user.id}/following?with_relationships=true") + + id = other_user.id + + assert [ + %{ + "id" => ^id, + "pleroma" => %{ + "relationship" => %{"id" => ^id, "following" => true, "followed_by" => false} + } + } + ] = json_response_and_validate_schema(conn, 200) + end + test "getting following, hide_follows, other user requesting" do user = insert(:user, hide_follows: true) other_user = insert(:user) @@ -1565,7 +1661,6 @@ test "getting a list of mutes" do result = conn - |> assign(:user, user) |> get("/api/v1/mutes") |> json_response_and_validate_schema(200) @@ -1573,7 +1668,6 @@ test "getting a list of mutes" do result = conn - |> assign(:user, user) |> get("/api/v1/mutes?limit=1") |> json_response_and_validate_schema(200) @@ -1581,7 +1675,6 @@ test "getting a list of mutes" do result = conn - |> assign(:user, user) |> get("/api/v1/mutes?since_id=#{id1}") |> json_response_and_validate_schema(200) @@ -1589,7 +1682,6 @@ test "getting a list of mutes" do result = conn - |> assign(:user, user) |> get("/api/v1/mutes?since_id=#{id1}&max_id=#{id3}") |> json_response_and_validate_schema(200) @@ -1597,13 +1689,45 @@ test "getting a list of mutes" do result = conn - |> assign(:user, user) |> get("/api/v1/mutes?since_id=#{id1}&limit=1") |> json_response_and_validate_schema(200) assert [%{"id" => ^id2}] = result end + test "list of mutes with with_relationships parameter" do + %{user: user, conn: conn} = oauth_access(["read:mutes"]) + %{id: id1} = other_user1 = insert(:user) + %{id: id2} = other_user2 = insert(:user) + %{id: id3} = other_user3 = insert(:user) + + {:ok, _, _} = User.follow(other_user1, user) + {:ok, _, _} = User.follow(other_user2, user) + {:ok, _, _} = User.follow(other_user3, user) + + {:ok, _} = User.mute(user, other_user1) + {:ok, _} = User.mute(user, other_user2) + {:ok, _} = User.mute(user, other_user3) + + assert [ + %{ + "id" => ^id1, + "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}} + }, + %{ + "id" => ^id2, + "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}} + }, + %{ + "id" => ^id3, + "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}} + } + ] = + conn + |> get("/api/v1/mutes?with_relationships=true") + |> json_response_and_validate_schema(200) + end + test "getting a list of blocks" do %{user: user, conn: conn} = oauth_access(["read:blocks"]) %{id: id1} = other_user1 = insert(:user) From f852e8d2d21657dae36871a8c0ef65e33192f8da Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Tue, 2 Feb 2021 12:03:20 -0600 Subject: [PATCH 3/3] Document we are disabling the extension fixup in Majic --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4f3bddb7..90bf3d999 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Reblog API Endpoint: Do not set visibility parameter to public by default and let CommonAPI to infer it from status, so a user can reblog their private status without explicitly setting reblog visibility to private. - Tag URLs in statuses are now absolute - Removed duplicate jobs to purge expired activities +- File extensions of some attachments were incorrectly changed. This feature has been disabled for now.
API Changes