From e7edfd9fec88af24869c3805a404f2b0a20914de Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Wed, 29 May 2019 12:20:18 -0500 Subject: [PATCH 1/5] Permit fetching statuses from API with nickname or id --- lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 2110027c3..bc75ab35a 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -330,7 +330,7 @@ def public_timeline(%{assigns: %{user: user}} = conn, params) do end def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do - with %User{} = user <- User.get_cached_by_id(params["id"]) do + with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"]) do activities = ActivityPub.fetch_user_activities(user, reading_user, params) conn From e912f81c828cc7e1d2c0dff8daed3ad52f407a61 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Wed, 29 May 2019 12:22:14 -0500 Subject: [PATCH 2/5] Update docs to reflect we accept nickname for id for both of these endpoints --- docs/api/differences_in_mastoapi_responses.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/api/differences_in_mastoapi_responses.md b/docs/api/differences_in_mastoapi_responses.md index 36b47608e..f952696f7 100644 --- a/docs/api/differences_in_mastoapi_responses.md +++ b/docs/api/differences_in_mastoapi_responses.md @@ -32,7 +32,10 @@ Has these additional fields under the `pleroma` object: ## Accounts -- `/api/v1/accounts/:id`: The `id` parameter can also be the `nickname` of the user. This only works in this endpoint, not the deeper nested ones for following etc. +The `id` parameter can also be the `nickname` of the user. This only works in these endpoints, not the deeper nested ones for following etc. + +- `/api/v1/accounts/:id` +- `/api/v1/accounts/:id/statuses` Has these additional fields under the `pleroma` object: From 46c7c53fbbfd9919d429ba15988af0da9e22d444 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Mon, 15 Jul 2019 17:10:33 -0500 Subject: [PATCH 3/5] Add changelog entry for Mastodon API change --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86c90da0b..599ea0a72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Mastodon API, extension: Ability to reset avatar, profile banner, and background - Mastodon API: Add support for categories for custom emojis by reusing the group feature. - Mastodon API: Add support for muting/unmuting notifications +- Mastodon API: /api/v1/accounts/:id/statuses now supports nicknames or user id - Admin API: Return users' tags when querying reports - Admin API: Return avatar and display name when querying users - Admin API: Allow querying user by ID From d0198fe215a7542ce506e40e1e4860a27ee2d01e Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Sat, 20 Jul 2019 13:03:34 +0300 Subject: [PATCH 4/5] [#1112] Preserving `id` on user insert conflict on order not to violate conversation_partipations_user_id_fkey constraint. --- CHANGELOG.md | 1 + lib/pleroma/user.ex | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e79b5420..f60f3ed97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Mastodon API: Embedded relationships not being properly rendered in the Account entity of Status entity - Mastodon API: Add `account_id`, `type`, `offset`, and `limit` to search API (`/api/v1/search` and `/api/v2/search`) - ActivityPub C2S: follower/following collection pages being inaccessible even when authentifucated if `hide_followers`/ `hide_follows` was set +- Existing user id not being preserved on insert conflict ### Added - MRF: Support for priming the mediaproxy cache (`Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index c91fbb68a..5ea2b518b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1211,7 +1211,7 @@ def insert_or_update_user(data) do data |> Map.put(:name, blank?(data[:name]) || data[:nickname]) |> remote_user_creation() - |> Repo.insert(on_conflict: :replace_all, conflict_target: :nickname) + |> Repo.insert(on_conflict: :replace_all_except_primary_key, conflict_target: :nickname) |> set_cache() end From 43a7cd27feb6ef52e4b130a974af3f819a9b266d Mon Sep 17 00:00:00 2001 From: Sergey Suprunenko Date: Sat, 20 Jul 2019 13:07:51 +0000 Subject: [PATCH 5/5] [tests] Mock :crypt.crypt/2 function in AuthenticationPlugTest --- test/plugs/authentication_plug_test.exs | 12 ++++-- test/signature_test.exs | 13 +++++-- test/upload_test.exs | 16 ++++++-- .../mastodon_api/search_controller_test.exs | 30 ++++++++------ test/web/ostatus/ostatus_controller_test.exs | 39 ++++++++++++------- 5 files changed, 73 insertions(+), 37 deletions(-) diff --git a/test/plugs/authentication_plug_test.exs b/test/plugs/authentication_plug_test.exs index b55e746f8..7ca045616 100644 --- a/test/plugs/authentication_plug_test.exs +++ b/test/plugs/authentication_plug_test.exs @@ -8,6 +8,9 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do alias Pleroma.Plugs.AuthenticationPlug alias Pleroma.User + import ExUnit.CaptureLog + import Mock + setup %{conn: conn} do user = %User{ id: 1, @@ -68,15 +71,18 @@ test "check sha512-crypt hash" do hash = "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" - assert AuthenticationPlug.checkpw("password", hash) - refute AuthenticationPlug.checkpw("password1", hash) + with_mock :crypt, crypt: fn _password, password_hash -> password_hash end do + assert AuthenticationPlug.checkpw("password", hash) + end end test "it returns false when hash invalid" do hash = "psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" - refute Pleroma.Plugs.AuthenticationPlug.checkpw("password", hash) + assert capture_log(fn -> + refute Pleroma.Plugs.AuthenticationPlug.checkpw("password", hash) + end) =~ "[error] Password hash not recognized" end end end diff --git a/test/signature_test.exs b/test/signature_test.exs index 840987cd6..7400cae9a 100644 --- a/test/signature_test.exs +++ b/test/signature_test.exs @@ -5,6 +5,7 @@ defmodule Pleroma.SignatureTest do use Pleroma.DataCase + import ExUnit.CaptureLog import Pleroma.Factory import Tesla.Mock @@ -46,8 +47,10 @@ test "it returns key" do end test "it returns error when not found user" do - assert Signature.fetch_public_key(make_fake_conn("test-ap_id")) == - {:error, :error} + assert capture_log(fn -> + assert Signature.fetch_public_key(make_fake_conn("test-ap_id")) == + {:error, :error} + end) =~ "[error] Could not decode user" end test "it returns error if public key is empty" do @@ -67,8 +70,10 @@ test "it returns key" do end test "it returns error when not found user" do - assert Signature.refetch_public_key(make_fake_conn("test-ap_id")) == - {:error, {:error, :ok}} + assert capture_log(fn -> + assert Signature.refetch_public_key(make_fake_conn("test-ap_id")) == + {:error, {:error, :ok}} + end) =~ "[error] Could not decode user" end end diff --git a/test/upload_test.exs b/test/upload_test.exs index f7b1893ad..32c6977d1 100644 --- a/test/upload_test.exs +++ b/test/upload_test.exs @@ -5,6 +5,8 @@ defmodule Pleroma.UploadTest do use Pleroma.DataCase + import ExUnit.CaptureLog + alias Pleroma.Upload alias Pleroma.Uploaders.Uploader @@ -77,8 +79,12 @@ def put_file(upload), do: TestUploaderBase.put_file(upload, __MODULE__) test "it returns error" do File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg") - assert Upload.store(@upload_file) == {:error, "Errors"} - Task.await(Agent.get(TestUploaderError, fn task_pid -> task_pid end)) + + assert capture_log(fn -> + assert Upload.store(@upload_file) == {:error, "Errors"} + Task.await(Agent.get(TestUploaderError, fn task_pid -> task_pid end)) + end) =~ + "[error] Elixir.Pleroma.Upload store (using Pleroma.UploadTest.TestUploaderError) failed: \"Errors\"" end end @@ -89,7 +95,11 @@ test "it returns error" do test "it returns error" do File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg") - assert Upload.store(@upload_file) == {:error, "Uploader callback timeout"} + + assert capture_log(fn -> + assert Upload.store(@upload_file) == {:error, "Uploader callback timeout"} + end) =~ + "[error] Elixir.Pleroma.Upload store (using Pleroma.UploadTest.TestUploader) failed: \"Uploader callback timeout\"" end end diff --git a/test/web/mastodon_api/search_controller_test.exs b/test/web/mastodon_api/search_controller_test.exs index 9f50c09f4..043b96c14 100644 --- a/test/web/mastodon_api/search_controller_test.exs +++ b/test/web/mastodon_api/search_controller_test.exs @@ -24,12 +24,16 @@ test "it returns empty result if user or status search return undefined error", {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]}, {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]} ] do - conn = get(conn, "/api/v2/search", %{"q" => "2hu"}) + capture_log(fn -> + results = + conn + |> get("/api/v2/search", %{"q" => "2hu"}) + |> json_response(200) - assert results = json_response(conn, 200) - - assert results["accounts"] == [] - assert results["statuses"] == [] + assert results["accounts"] == [] + assert results["statuses"] == [] + end) =~ + "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}" end end @@ -99,14 +103,16 @@ test "it returns empty result if user or status search return undefined error", {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]}, {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]} ] do - conn = - conn - |> get("/api/v1/search", %{"q" => "2hu"}) + capture_log(fn -> + results = + conn + |> get("/api/v1/search", %{"q" => "2hu"}) + |> json_response(200) - assert results = json_response(conn, 200) - - assert results["accounts"] == [] - assert results["statuses"] == [] + assert results["accounts"] == [] + assert results["statuses"] == [] + end) =~ + "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}" end end diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 3dd8c6491..bb7648bdd 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -4,7 +4,10 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do use Pleroma.Web.ConnCase + + import ExUnit.CaptureLog import Pleroma.Factory + alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.CommonAPI @@ -27,24 +30,28 @@ test "decodes a salmon", %{conn: conn} do user = insert(:user) salmon = File.read!("test/fixtures/salmon.xml") - conn = - conn - |> put_req_header("content-type", "application/atom+xml") - |> post("/users/#{user.nickname}/salmon", salmon) + assert capture_log(fn -> + conn = + conn + |> put_req_header("content-type", "application/atom+xml") + |> post("/users/#{user.nickname}/salmon", salmon) - assert response(conn, 200) + assert response(conn, 200) + end) =~ "[error]" end test "decodes a salmon with a changed magic key", %{conn: conn} do user = insert(:user) salmon = File.read!("test/fixtures/salmon.xml") - conn = - conn - |> put_req_header("content-type", "application/atom+xml") - |> post("/users/#{user.nickname}/salmon", salmon) + assert capture_log(fn -> + conn = + conn + |> put_req_header("content-type", "application/atom+xml") + |> post("/users/#{user.nickname}/salmon", salmon) - assert response(conn, 200) + assert response(conn, 200) + end) =~ "[error]" # Set a wrong magic-key for a user so it has to refetch salmon_user = User.get_cached_by_ap_id("http://gs.example.org:4040/index.php/user/1") @@ -61,12 +68,14 @@ test "decodes a salmon with a changed magic key", %{conn: conn} do |> Ecto.Changeset.put_embed(:info, info_cng) |> User.update_and_set_cache() - conn = - build_conn() - |> put_req_header("content-type", "application/atom+xml") - |> post("/users/#{user.nickname}/salmon", salmon) + assert capture_log(fn -> + conn = + build_conn() + |> put_req_header("content-type", "application/atom+xml") + |> post("/users/#{user.nickname}/salmon", salmon) - assert response(conn, 200) + assert response(conn, 200) + end) =~ "[error]" end end