From 50585d051b9366903943f7388219ac96af6c8621 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:04:42 +0100 Subject: [PATCH 01/44] Add User.Info module To validate and mutate the user.info field. --- lib/pleroma/user/info.ex | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lib/pleroma/user/info.ex diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex new file mode 100644 index 000000000..e13537226 --- /dev/null +++ b/lib/pleroma/user/info.ex @@ -0,0 +1,27 @@ +defmodule Pleroma.User.Info do + use Ecto.Schema + import Ecto.Changeset + + embedded_schema do + field :banner, :map, default: %{} + field :source_data, :map, default: %{} + field :note_count, :integer, default: 0 + field :follower_count, :integer, default: 0 + field :locked, :boolean, default: false + field :default_scope, :string, default: "public" + field :blocks, {:array, :string}, default: [] + field :domain_blocks, {:array, :string}, default: [] + field :deactivated, :boolean, default: false + field :no_rich_text, :boolean, default: false + field :ap_enabled, :boolean, default: false + field :keys, :map, default: %{} + end + + def set_activation_status(info, deactivated) do + params = %{deactivated: deactivated} + + info + |> cast(params, [:deactivated]) + |> validate_required([:deactivated]) + end +end From 47d883d3abb4d64721b2a8ed925021dfeeaa4459 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:06:02 +0100 Subject: [PATCH 02/44] Fix User deactivation. --- lib/pleroma/user.ex | 18 ++++++++++-------- test/support/factory.ex | 3 ++- test/user_test.exs | 6 +++--- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 6e1d5559d..7336e8540 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -19,11 +19,11 @@ defmodule Pleroma.User do field(:ap_id, :string) field(:avatar, :map) field(:local, :boolean, default: true) - field(:info, :map, default: %{}) field(:follower_address, :string) field(:search_distance, :float, virtual: true) field(:last_refreshed_at, :naive_datetime) has_many(:notifications, Notification) + embeds_one :info, Pleroma.User.Info timestamps() end @@ -71,10 +71,10 @@ def user_info(%User{} = user) do %{ following_count: length(user.following) - oneself, - note_count: user.info["note_count"] || 0, - follower_count: user.info["follower_count"] || 0, - locked: user.info["locked"] || false, - default_scope: user.info["default_scope"] || "public" + note_count: user.info.note_count, + follower_count: user.info.follower_count, + locked: user.info.locked, + default_scope: user.info.default_scope } end @@ -613,9 +613,11 @@ def moderator_user_query() do end def deactivate(%User{} = user, status \\ true) do - new_info = Map.put(user.info, "deactivated", status) - cs = User.info_changeset(user, %{info: new_info}) - update_and_set_cache(cs) + info_cng = User.Info.set_activation_status(user.info, status) + cng = change(user) + |> put_embed(:info, info_cng) + + update_and_set_cache(cng) end def delete(%User{} = user) do diff --git a/test/support/factory.ex b/test/support/factory.ex index 4f5060abf..2889d8977 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -7,7 +7,8 @@ def user_factory do email: sequence(:email, &"user#{&1}@example.com"), nickname: sequence(:nickname, &"nick#{&1}"), password_hash: Comeonin.Pbkdf2.hashpwsalt("test"), - bio: sequence(:bio, &"Tester Number #{&1}") + bio: sequence(:bio, &"Tester Number #{&1}"), + info: %{} } %{ diff --git a/test/user_test.exs b/test/user_test.exs index 231f1d94d..d6a3c9979 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -489,11 +489,11 @@ test "get recipients from activity" do test ".deactivate can de-activate then re-activate a user" do user = insert(:user) - assert false == !!user.info["deactivated"] + assert false == user.info.deactivated {:ok, user} = User.deactivate(user) - assert true == user.info["deactivated"] + assert true == user.info.deactivated {:ok, user} = User.deactivate(user, false) - assert false == !!user.info["deactivated"] + assert false == user.info.deactivated end test ".delete deactivates a user, all follow relationships and all create activities" do From 5c8f07f0a8594204ab45a7db262db09b71f94574 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:17:56 +0100 Subject: [PATCH 03/44] Fix note counting. --- lib/pleroma/user.ex | 19 ++++++++----------- lib/pleroma/user/info.ex | 8 ++++++++ test/user_test.exs | 14 +++++++------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 7336e8540..b33ebb565 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -411,22 +411,19 @@ def get_follow_requests(%User{} = user) do end def increase_note_count(%User{} = user) do - note_count = (user.info["note_count"] || 0) + 1 - new_info = Map.put(user.info, "note_count", note_count) + info_cng = User.Info.add_to_note_count(user.info, 1) + cng = change(user) + |> put_embed(:info, info_cng) - cs = info_changeset(user, %{info: new_info}) - - update_and_set_cache(cs) + update_and_set_cache(cng) end def decrease_note_count(%User{} = user) do - note_count = user.info["note_count"] || 0 - note_count = if note_count <= 0, do: 0, else: note_count - 1 - new_info = Map.put(user.info, "note_count", note_count) + info_cng = User.Info.add_to_note_count(user.info, -1) + cng = change(user) + |> put_embed(:info, info_cng) - cs = info_changeset(user, %{info: new_info}) - - update_and_set_cache(cs) + update_and_set_cache(cng) end def update_note_count(%User{} = user) do diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index e13537226..465a14d91 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -24,4 +24,12 @@ def set_activation_status(info, deactivated) do |> cast(params, [:deactivated]) |> validate_required([:deactivated]) end + + def add_to_note_count(info, number) do + params = %{note_count: Enum.max([0, info.note_count + number])} + + info + |> cast(params, [:note_count]) + |> validate_required([:note_count]) + end end diff --git a/test/user_test.exs b/test/user_test.exs index d6a3c9979..340878f64 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -322,34 +322,34 @@ test "it increases the info->note_count property" do note = insert(:note) user = User.get_by_ap_id(note.data["actor"]) - assert user.info["note_count"] == nil + assert user.info.note_count == 0 {:ok, user} = User.increase_note_count(user) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 {:ok, user} = User.increase_note_count(user) - assert user.info["note_count"] == 2 + assert user.info.note_count == 2 end test "it decreases the info->note_count property" do note = insert(:note) user = User.get_by_ap_id(note.data["actor"]) - assert user.info["note_count"] == nil + assert user.info.note_count == 0 {:ok, user} = User.increase_note_count(user) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 {:ok, user} = User.decrease_note_count(user) - assert user.info["note_count"] == 0 + assert user.info.note_count == 0 {:ok, user} = User.decrease_note_count(user) - assert user.info["note_count"] == 0 + assert user.info.note_count == 0 end test "it sets the info->follower_count property" do From b396dba425e9e532ad9bb2ddcda9c74da29e200d Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:24:16 +0100 Subject: [PATCH 04/44] Fix follower count setting. --- lib/pleroma/user.ex | 8 +++++--- lib/pleroma/user/info.ex | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b33ebb565..5603d1f5f 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -454,11 +454,13 @@ def update_follower_count(%User{} = user) do follower_count = Repo.one(follower_count_query) - new_info = Map.put(user.info, "follower_count", follower_count) + info_cng = user.info + |> User.Info.set_follower_count(follower_count) - cs = info_changeset(user, %{info: new_info}) + cng = change(user) + |> put_embed(:info, info_cng) - update_and_set_cache(cs) + update_and_set_cache(cng) end def get_users_from_set_query(ap_ids, false) do diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 465a14d91..49b52d5da 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -32,4 +32,12 @@ def add_to_note_count(info, number) do |> cast(params, [:note_count]) |> validate_required([:note_count]) end + + def set_follower_count(info, number) do + params = %{follower_count: Enum.max([0, number])} + + info + |> cast(params, [:follower_count]) + |> validate_required([:follower_count]) + end end From 756764266cb5319a775845635b91b04aacf16aae Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:27:04 +0100 Subject: [PATCH 05/44] Formatting. --- lib/pleroma/user.ex | 30 +++++++++++++++++++----------- lib/pleroma/user/info.ex | 27 ++++++++++++++------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 5603d1f5f..7b0edee75 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -23,7 +23,7 @@ defmodule Pleroma.User do field(:search_distance, :float, virtual: true) field(:last_refreshed_at, :naive_datetime) has_many(:notifications, Notification) - embeds_one :info, Pleroma.User.Info + embeds_one(:info, Pleroma.User.Info) timestamps() end @@ -412,16 +412,20 @@ def get_follow_requests(%User{} = user) do def increase_note_count(%User{} = user) do info_cng = User.Info.add_to_note_count(user.info, 1) - cng = change(user) - |> put_embed(:info, info_cng) + + cng = + change(user) + |> put_embed(:info, info_cng) update_and_set_cache(cng) end def decrease_note_count(%User{} = user) do info_cng = User.Info.add_to_note_count(user.info, -1) - cng = change(user) - |> put_embed(:info, info_cng) + + cng = + change(user) + |> put_embed(:info, info_cng) update_and_set_cache(cng) end @@ -454,11 +458,13 @@ def update_follower_count(%User{} = user) do follower_count = Repo.one(follower_count_query) - info_cng = user.info - |> User.Info.set_follower_count(follower_count) + info_cng = + user.info + |> User.Info.set_follower_count(follower_count) - cng = change(user) - |> put_embed(:info, info_cng) + cng = + change(user) + |> put_embed(:info, info_cng) update_and_set_cache(cng) end @@ -613,8 +619,10 @@ def moderator_user_query() do def deactivate(%User{} = user, status \\ true) do info_cng = User.Info.set_activation_status(user.info, status) - cng = change(user) - |> put_embed(:info, info_cng) + + cng = + change(user) + |> put_embed(:info, info_cng) update_and_set_cache(cng) end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 49b52d5da..da5e26ebd 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -3,18 +3,19 @@ defmodule Pleroma.User.Info do import Ecto.Changeset embedded_schema do - field :banner, :map, default: %{} - field :source_data, :map, default: %{} - field :note_count, :integer, default: 0 - field :follower_count, :integer, default: 0 - field :locked, :boolean, default: false - field :default_scope, :string, default: "public" - field :blocks, {:array, :string}, default: [] - field :domain_blocks, {:array, :string}, default: [] - field :deactivated, :boolean, default: false - field :no_rich_text, :boolean, default: false - field :ap_enabled, :boolean, default: false - field :keys, :map, default: %{} + field(:banner, :map, default: %{}) + field(:source_data, :map, default: %{}) + field(:note_count, :integer, default: 0) + field(:follower_count, :integer, default: 0) + field(:locked, :boolean, default: false) + field(:default_scope, :string, default: "public") + field(:blocks, {:array, :string}, default: []) + field(:domain_blocks, {:array, :string}, default: []) + field(:deactivated, :boolean, default: false) + field(:no_rich_text, :boolean, default: false) + field(:ap_enabled, :boolean, default: false) + field(:is_moderator, :boolean, default: false) + field(:keys, :map, default: %{}) end def set_activation_status(info, deactivated) do @@ -26,7 +27,7 @@ def set_activation_status(info, deactivated) do end def add_to_note_count(info, number) do - params = %{note_count: Enum.max([0, info.note_count + number])} + params = %{note_count: Enum.max([0, number])} info |> cast(params, [:note_count]) From 812f5b058a3475e3b74780af8a250d941d8326d9 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:40:31 +0100 Subject: [PATCH 06/44] Fix blocking. --- lib/pleroma/user.ex | 34 ++++++++++++++++++++-------------- lib/pleroma/user/info.ex | 16 ++++++++++++++++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 7b0edee75..3a0f78274 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -550,12 +550,15 @@ def block(blocker, %User{ap_id: ap_id} = blocked) do unfollow(blocked, blocker) end - blocks = blocker.info["blocks"] || [] - new_blocks = Enum.uniq([ap_id | blocks]) - new_info = Map.put(blocker.info, "blocks", new_blocks) + info_cng = + blocker.info + |> User.Info.add_to_block(ap_id) - cs = User.info_changeset(blocker, %{info: new_info}) - update_and_set_cache(cs) + cng = + change(blocker) + |> put_embed(:info, info_cng) + + update_and_set_cache(cng) end # helper to handle the block given only an actor's AP id @@ -563,18 +566,21 @@ def block(blocker, %{ap_id: ap_id}) do block(blocker, User.get_by_ap_id(ap_id)) end - def unblock(user, %{ap_id: ap_id}) do - blocks = user.info["blocks"] || [] - new_blocks = List.delete(blocks, ap_id) - new_info = Map.put(user.info, "blocks", new_blocks) + def unblock(blocker, %{ap_id: ap_id}) do + info_cng = + blocker.info + |> User.Info.remove_from_block(ap_id) - cs = User.info_changeset(user, %{info: new_info}) - update_and_set_cache(cs) + cng = + change(blocker) + |> put_embed(:info, info_cng) + + update_and_set_cache(cng) end def blocks?(user, %{ap_id: ap_id}) do - blocks = user.info["blocks"] || [] - domain_blocks = user.info["domain_blocks"] || [] + blocks = user.info.blocks + domain_blocks = user.info.domain_blocks %{host: host} = URI.parse(ap_id) Enum.member?(blocks, ap_id) || @@ -584,7 +590,7 @@ def blocks?(user, %{ap_id: ap_id}) do end def block_domain(user, domain) do - domain_blocks = user.info["domain_blocks"] || [] + domain_blocks = user.info.domain_blocks new_blocks = Enum.uniq([domain | domain_blocks]) new_info = Map.put(user.info, "domain_blocks", new_blocks) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index da5e26ebd..cae5562f0 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -41,4 +41,20 @@ def set_follower_count(info, number) do |> cast(params, [:follower_count]) |> validate_required([:follower_count]) end + + def set_blocks(info, blocks) do + params = %{blocks: blocks} + + info + |> cast(params, [:blocks]) + |> validate_required([:blocks]) + end + + def add_to_block(info, blocked) do + set_blocks(info, Enum.uniq([blocked | info.blocks])) + end + + def remove_from_block(info, blocked) do + set_blocks(info, List.delete(info.blocks, blocked)) + end end From 8e3d8bde04bc3a6f82b501a39df12a672f0f7141 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:40:58 +0100 Subject: [PATCH 07/44] Fix user deactivation test. --- test/user_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/user_test.exs b/test/user_test.exs index 340878f64..6ef88e492 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -41,7 +41,7 @@ test "follow takes a user and another user" do test "can't follow a deactivated users" do user = insert(:user) - followed = insert(:user, info: %{"deactivated" => true}) + followed = insert(:user, info: %{deactivated: true}) {:error, _} = User.follow(user, followed) end From 6f90ceb2eda68c5541a584d46868de748077c85d Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:46:04 +0100 Subject: [PATCH 08/44] Fix follower count test. --- lib/pleroma/user.ex | 2 +- test/user_test.exs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 3a0f78274..64b6c0aa1 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -222,7 +222,7 @@ def follow(%User{} = follower, %User{info: info} = followed) do ap_followers = followed.follower_address cond do - following?(follower, followed) or info["deactivated"] -> + following?(follower, followed) or info.deactivated -> {:error, "Could not follow user: #{followed.nickname} is already on your list."} deny_follow_blocked and blocks?(followed, follower) -> diff --git a/test/user_test.exs b/test/user_test.exs index 6ef88e492..fdc908dcd 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -34,7 +34,7 @@ test "follow takes a user and another user" do user = Repo.get(User, user.id) followed = User.get_by_ap_id(followed.ap_id) - assert followed.info["follower_count"] == 1 + assert followed.info.follower_count == 1 assert User.ap_followers(followed) in user.following end @@ -358,11 +358,11 @@ test "it sets the info->follower_count property" do User.follow(follower, user) - assert user.info["follower_count"] == nil + assert user.info.follower_count == 0 {:ok, user} = User.update_follower_count(user) - assert user.info["follower_count"] == 1 + assert user.info.follower_count == 1 end end @@ -517,7 +517,7 @@ test ".delete deactivates a user, all follow relationships and all create activi follower = Repo.get(User, follower.id) user = Repo.get(User, user.id) - assert user.info["deactivated"] + assert user.info.deactivated refute User.following?(user, followed) refute User.following?(followed, follower) From d5af41b577c773ab6c3918d395ff4973a017a797 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:52:21 +0100 Subject: [PATCH 09/44] Fix note count update. --- lib/pleroma/user.ex | 8 +++++--- lib/pleroma/user/info.ex | 4 ++++ test/user_test.exs | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 64b6c0aa1..b3d0712d4 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -440,11 +440,13 @@ def update_note_count(%User{} = user) do note_count = Repo.one(note_count_query) - new_info = Map.put(user.info, "note_count", note_count) + info_cng = User.Info.set_note_count(user.info, note_count) - cs = info_changeset(user, %{info: new_info}) + cng = + change(user) + |> put_embed(:info, info_cng) - update_and_set_cache(cs) + update_and_set_cache(cng) end def update_follower_count(%User{} = user) do diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index cae5562f0..619e58b16 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -27,6 +27,10 @@ def set_activation_status(info, deactivated) do end def add_to_note_count(info, number) do + set_note_count(info, info.note_count + number) + end + + def set_note_count(info, number) do params = %{note_count: Enum.max([0, number])} info diff --git a/test/user_test.exs b/test/user_test.exs index fdc908dcd..3d330b963 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -311,11 +311,11 @@ test "it sets the info->note_count property" do user = User.get_by_ap_id(note.data["actor"]) - assert user.info["note_count"] == nil + assert user.info.note_count == 0 {:ok, user} = User.update_note_count(user) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 end test "it increases the info->note_count property" do From fc3bcf335e2c5ba1f8b1b25c1a4869cefff2a431 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 18:53:50 +0100 Subject: [PATCH 10/44] Fix following locked users. --- lib/pleroma/user.ex | 2 +- test/user_test.exs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b3d0712d4..af2a696a9 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -191,7 +191,7 @@ def needs_update?(%User{local: false} = user) do def needs_update?(_), do: true - def maybe_direct_follow(%User{} = follower, %User{local: true, info: %{"locked" => true}}) do + def maybe_direct_follow(%User{} = follower, %User{local: true, info: %{locked: true}}) do {:ok, follower} end diff --git a/test/user_test.exs b/test/user_test.exs index 3d330b963..f37f4521d 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -56,8 +56,8 @@ test "can't follow a user who blocked us" do end test "local users do not automatically follow local locked accounts" do - follower = insert(:user, info: %{"locked" => true}) - followed = insert(:user, info: %{"locked" => true}) + follower = insert(:user, info: %{locked: true}) + followed = insert(:user, info: %{locked: true}) {:ok, follower} = User.maybe_direct_follow(follower, followed) From e7cd6e97394a80ed3ef794e801183cc0635f8a15 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 19:33:43 +0100 Subject: [PATCH 11/44] Fix setting of keys. --- lib/pleroma/user/info.ex | 10 +++++++++- lib/pleroma/web/web_finger/web_finger.ex | 14 +++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 619e58b16..39a1291dd 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -15,7 +15,7 @@ defmodule Pleroma.User.Info do field(:no_rich_text, :boolean, default: false) field(:ap_enabled, :boolean, default: false) field(:is_moderator, :boolean, default: false) - field(:keys, :map, default: %{}) + field(:keys, :string, default: nil) end def set_activation_status(info, deactivated) do @@ -61,4 +61,12 @@ def add_to_block(info, blocked) do def remove_from_block(info, blocked) do set_blocks(info, List.delete(info.blocks, blocked)) end + + def set_keys(info, keys) do + params = %{keys: keys} + + info + |> cast(params, [:keys]) + |> validate_required([:keys]) + end end diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 9f554d286..18cdc057e 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -113,16 +113,20 @@ def represent_user(user, "XML") do # This seems a better fit in Salmon def ensure_keys_present(user) do - info = user.info || %{} + info = user.info - if info["keys"] do + if info.keys do {:ok, user} else {:ok, pem} = Salmon.generate_rsa_pem() - info = Map.put(info, "keys", pem) - Ecto.Changeset.change(user, info: info) - |> User.update_and_set_cache() + info_cng = info + |> Pleroma.User.Info.set_keys(pem) + + cng = Ecto.Changeset.change(user) + |> Ecto.Changeset.put_embed(:info, info_cng) + + User.update_and_set_cache(cng) end end From 4c918392c61ca30f46d8e5f8e964993844b70ad8 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 21:40:52 +0100 Subject: [PATCH 12/44] Fix most User tests. --- lib/pleroma/formatter.ex | 4 +- lib/pleroma/user.ex | 43 ++++++++++++-------- lib/pleroma/user/info.ex | 21 ++++++++++ lib/pleroma/web/activity_pub/activity_pub.ex | 2 +- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 26bb17377..1a5c07c8a 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -116,8 +116,8 @@ def add_user_links({subs, text}, mentions) do subs ++ Enum.map(mentions, fn {match, %User{ap_id: ap_id, info: info}, uuid} -> ap_id = - if is_binary(info["source_data"]["url"]) do - info["source_data"]["url"] + if is_binary(info.source_data["url"]) do + info.source_data["url"] else ap_id end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index af2a696a9..23e0346a5 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -36,13 +36,13 @@ def avatar_url(user) do end def banner_url(user) do - case user.info["banner"] do + case user.info.banner do %{"url" => [%{"href" => href} | _]} -> href _ -> "#{Web.base_url()}/images/banner.png" end end - def profile_url(%User{info: %{"source_data" => %{"url" => url}}}), do: url + def profile_url(%User{info: %{source_data: %{"url" => url}}}), do: url def profile_url(%User{ap_id: ap_id}), do: ap_id def profile_url(_), do: nil @@ -80,18 +80,24 @@ def user_info(%User{} = user) do @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ def remote_user_creation(params) do + params = params + |> Map.put(:info, params[:info] || %{}) + + info_cng = User.Info.remote_user_creation(%User.Info{}, params[:info]) + changes = - %User{} - |> cast(params, [:bio, :name, :ap_id, :nickname, :info, :avatar]) + %User{info: %{}} + |> cast(params, [:bio, :name, :ap_id, :nickname, :avatar]) |> validate_required([:name, :ap_id]) |> unique_constraint(:nickname) |> validate_format(:nickname, @email_regex) |> validate_length(:bio, max: 5000) |> validate_length(:name, max: 100) |> put_change(:local, false) + |> put_embed(:info, info_cng) if changes.valid? do - case changes.changes[:info]["source_data"] do + case info_cng.changes[:source_data] do %{"followers" => followers} -> changes |> put_change(:follower_address, followers) @@ -592,21 +598,23 @@ def blocks?(user, %{ap_id: ap_id}) do end def block_domain(user, domain) do - domain_blocks = user.info.domain_blocks - new_blocks = Enum.uniq([domain | domain_blocks]) - new_info = Map.put(user.info, "domain_blocks", new_blocks) + info_cng = user.info + |> User.Info.add_to_domain_block(domain) - cs = User.info_changeset(user, %{info: new_info}) - update_and_set_cache(cs) + cng = change(user) + |> put_embed(:info, info_cng) + + update_and_set_cache(cng) end def unblock_domain(user, domain) do - blocks = user.info["domain_blocks"] || [] - new_blocks = List.delete(blocks, domain) - new_info = Map.put(user.info, "domain_blocks", new_blocks) + info_cng = user.info + |> User.Info.remove_from_domain_block(domain) - cs = User.info_changeset(user, %{info: new_info}) - update_and_set_cache(cs) + cng = change(user) + |> put_embed(:info, info_cng) + + update_and_set_cache(cng) end def local_user_query() do @@ -700,7 +708,7 @@ def get_or_create_instance_user do user else changes = - %User{} + %User{info: %{}} |> cast(%{}, [:ap_id, :nickname, :local]) |> put_change(:ap_id, relay_uri) |> put_change(:nickname, nil) @@ -745,13 +753,14 @@ def insert_or_update_user(data) do data = data |> Map.put(:name, blank?(data[:name]) || data[:nickname]) + |> Map.put(:info, data[:info] || %{}) cs = User.remote_user_creation(data) Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname) end def ap_enabled?(%User{local: true}), do: true - def ap_enabled?(%User{info: info}), do: info["ap_enabled"] + def ap_enabled?(%User{info: info}), do: info.ap_enabled def ap_enabled?(_), do: false def get_or_fetch(uri_or_nickname) do diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 39a1291dd..4a4c620ed 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -62,6 +62,22 @@ def remove_from_block(info, blocked) do set_blocks(info, List.delete(info.blocks, blocked)) end + def set_domain_blocks(info, domain_blocks) do + params = %{domain_blocks: domain_blocks} + + info + |> cast(params, [:domain_blocks]) + |> validate_required([:domain_blocks]) + end + + def add_to_domain_block(info, domain_blocked) do + set_domain_blocks(info, Enum.uniq([domain_blocked | info.domain_blocks])) + end + + def remove_from_domain_block(info, domain_blocked) do + set_domain_blocks(info, List.delete(info.domain_blocks, domain_blocked)) + end + def set_keys(info, keys) do params = %{keys: keys} @@ -69,4 +85,9 @@ def set_keys(info, keys) do |> cast(params, [:keys]) |> validate_required([:keys]) end + + def remote_user_creation(info, params) do + info + |> cast(params, [:source_data]) + end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index ed579e336..54ca891b9 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -42,7 +42,7 @@ defp get_recipients(data) do defp check_actor_is_active(actor) do if not is_nil(actor) do with user <- User.get_cached_by_ap_id(actor), - false <- !!user.info["deactivated"] do + false <- user.info.deactivated do :ok else _e -> :reject From cafa15131a59ae404eaa48d056885db1f052c9ed Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 21:41:35 +0100 Subject: [PATCH 13/44] Mix format. --- lib/pleroma/user.ex | 25 ++++++++++++++---------- lib/pleroma/web/web_finger/web_finger.ex | 10 ++++++---- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 23e0346a5..e71b33304 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -80,8 +80,9 @@ def user_info(%User{} = user) do @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ def remote_user_creation(params) do - params = params - |> Map.put(:info, params[:info] || %{}) + params = + params + |> Map.put(:info, params[:info] || %{}) info_cng = User.Info.remote_user_creation(%User.Info{}, params[:info]) @@ -598,21 +599,25 @@ def blocks?(user, %{ap_id: ap_id}) do end def block_domain(user, domain) do - info_cng = user.info - |> User.Info.add_to_domain_block(domain) + info_cng = + user.info + |> User.Info.add_to_domain_block(domain) - cng = change(user) - |> put_embed(:info, info_cng) + cng = + change(user) + |> put_embed(:info, info_cng) update_and_set_cache(cng) end def unblock_domain(user, domain) do - info_cng = user.info - |> User.Info.remove_from_domain_block(domain) + info_cng = + user.info + |> User.Info.remove_from_domain_block(domain) - cng = change(user) - |> put_embed(:info, info_cng) + cng = + change(user) + |> put_embed(:info, info_cng) update_and_set_cache(cng) end diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 18cdc057e..5bf529840 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -120,11 +120,13 @@ def ensure_keys_present(user) do else {:ok, pem} = Salmon.generate_rsa_pem() - info_cng = info - |> Pleroma.User.Info.set_keys(pem) + info_cng = + info + |> Pleroma.User.Info.set_keys(pem) - cng = Ecto.Changeset.change(user) - |> Ecto.Changeset.put_embed(:info, info_cng) + cng = + Ecto.Changeset.change(user) + |> Ecto.Changeset.put_embed(:info, info_cng) User.update_and_set_cache(cng) end From 40d9d2098c85f1a8a6a5ff2b17adc78bbba3fd6c Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 22:15:03 +0100 Subject: [PATCH 14/44] Fix user updating from AP. --- lib/pleroma/user.ex | 7 ++++++- lib/pleroma/user/info.ex | 6 ++++++ lib/pleroma/web/activity_pub/transmogrifier.ex | 4 ---- test/user_test.exs | 4 +++- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index e71b33304..565218b4c 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -128,12 +128,17 @@ def upgrade_changeset(struct, params \\ %{}) do params |> Map.put(:last_refreshed_at, NaiveDateTime.utc_now()) + info_cng = + struct.info + |> User.Info.user_upgrade(params[:info]) + struct - |> cast(params, [:bio, :name, :info, :follower_address, :avatar, :last_refreshed_at]) + |> cast(params, [:bio, :name, :follower_address, :avatar, :last_refreshed_at]) |> unique_constraint(:nickname) |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/) |> validate_length(:bio, max: 5000) |> validate_length(:name, max: 100) + |> put_embed(:info, info_cng) end def password_update_changeset(struct, params) do diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 4a4c620ed..b664af81c 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -90,4 +90,10 @@ def remote_user_creation(info, params) do info |> cast(params, [:source_data]) end + + # Receives data from user_data_from_user_object + def user_upgrade(info, params) do + info + |> cast(params, [:ap_enabled, :source_data, :banner, :locked]) + end end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 5864855b0..2d11c40c5 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -850,10 +850,6 @@ defp user_upgrade_task(user) do def upgrade_user_from_ap_id(ap_id, async \\ true) do with %User{local: false} = user <- User.get_by_ap_id(ap_id), {:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id) do - data = - data - |> Map.put(:info, Map.merge(user.info, data[:info])) - already_ap = User.ap_enabled?(user) {:ok, user} = diff --git a/test/user_test.exs b/test/user_test.exs index f37f4521d..f345f001f 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -185,12 +185,14 @@ test "updates an existing user, if stale" do local: false, nickname: "admin@mastodon.example.org", ap_id: "http://mastodon.example.org/users/admin", - last_refreshed_at: a_week_ago + last_refreshed_at: a_week_ago, + info: %{} ) assert orig_user.last_refreshed_at == a_week_ago user = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin") + assert user.info.source_data["endpoints"] refute user.last_refreshed_at == orig_user.last_refreshed_at end From fbb70d25fe28177b8d053d1055942abc7e7a3db9 Mon Sep 17 00:00:00 2001 From: lain Date: Sun, 18 Nov 2018 22:36:47 +0100 Subject: [PATCH 15/44] Several twitter api fixes. --- lib/pleroma/user/info.ex | 1 + lib/pleroma/web/twitter_api/twitter_api.ex | 10 +--------- lib/pleroma/web/twitter_api/views/user_view.ex | 14 +++++++------- test/web/twitter_api/twitter_api_test.exs | 10 +++++----- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index b664af81c..48f3a4d4a 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -4,6 +4,7 @@ defmodule Pleroma.User.Info do embedded_schema do field(:banner, :map, default: %{}) + field(:background, :string, default: nil) field(:source_data, :map, default: %{}) field(:note_count, :integer, default: 0) field(:follower_count, :integer, default: 0) diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 5bfb83b1e..d98deeb03 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -148,7 +148,7 @@ def register_user(params) do cond do registrations_open || (!is_nil(token) && !token.used) -> - changeset = User.register_changeset(%User{}, params) + changeset = User.register_changeset(%User{info: %{}}, params) with {:ok, user} <- Repo.insert(changeset) do !registrations_open && UserInviteToken.mark_as_used(token.token) @@ -279,14 +279,6 @@ def conversation_id_to_context(id) do def get_external_profile(for_user, uri) do with %User{} = user <- User.get_or_fetch(uri) do - spawn(fn -> - with url <- user.info["topic"], - {:ok, %{body: body}} <- - @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do - OStatus.handle_incoming(body) - end - end) - {:ok, UserView.render("show.json", %{user: user, for: for_user})} else _e -> diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index a100a1127..b78024ed7 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -31,7 +31,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do user_info = User.get_cached_user_info(user) emoji = - (user.info["source_data"]["tag"] || []) + (user.info.source_data["tag"] || []) |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end) |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} -> {String.trim(name, ":"), url} @@ -40,7 +40,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do # ``fields`` is an array of mastodon profile field, containing ``{"name": "…", "value": "…"}``. # For example: [{"name": "Pronoun", "value": "she/her"}, …] fields = - (user.info["source_data"]["attachment"] || []) + (user.info.source_data["attachment"] || []) |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end) |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end) @@ -66,17 +66,17 @@ def render("user.json", %{user: user = %User{}} = assigns) do "profile_image_url_profile_size" => image, "profile_image_url_original" => image, "rights" => %{ - "delete_others_notice" => !!user.info["is_moderator"] + "delete_others_notice" => !!user.info.is_moderator }, "screen_name" => user.nickname, "statuses_count" => user_info[:note_count], "statusnet_profile_url" => user.ap_id, "cover_photo" => User.banner_url(user) |> MediaProxy.url(), - "background_image" => image_url(user.info["background"]) |> MediaProxy.url(), + "background_image" => image_url(user.info.background) |> MediaProxy.url(), "is_local" => user.local, - "locked" => !!user.info["locked"], - "default_scope" => user.info["default_scope"] || "public", - "no_rich_text" => user.info["no_rich_text"] || false, + "locked" => user.info.locked, + "default_scope" => user.info.default_scope, + "no_rich_text" => user.info.no_rich_text, "fields" => fields } diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 8b9920bd9..ec13b89d4 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -10,7 +10,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do test "create a status" do user = insert(:user) - _mentioned_user = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"}) + _mentioned_user = insert(:user, %{nickname: "shp", ap_id: "shp"}) object_data = %{ "type" => "Image", @@ -67,7 +67,7 @@ test "create a status" do user = User.get_by_ap_id(user.ap_id) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 end test "create a status that is a reply" do @@ -116,7 +116,7 @@ test "Follow another user using screen_name" do assert User.ap_followers(followed) in user.following followed = User.get_by_ap_id(followed.ap_id) - assert followed.info["follower_count"] == 1 + assert followed.info.follower_count == 1 {:error, msg} = TwitterAPI.follow(user, %{"screen_name" => followed.nickname}) assert msg == "Could not follow user: #{followed.nickname} is already on your list." @@ -169,7 +169,7 @@ test "Unblock another user using user_id" do {:ok, user, _unblocked} = TwitterAPI.block(user, %{"user_id" => unblocked.id}) {:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"user_id" => unblocked.id}) - assert user.info["blocks"] == [] + assert user.info.blocks == [] end test "Unblock another user using screen_name" do @@ -178,7 +178,7 @@ test "Unblock another user using screen_name" do {:ok, user, _unblocked} = TwitterAPI.block(user, %{"screen_name" => unblocked.nickname}) {:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"screen_name" => unblocked.nickname}) - assert user.info["blocks"] == [] + assert user.info.blocks == [] end test "upload a file" do From 2887f4ff1d32c8fbe7a90ac921823794264f7157 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 20 Nov 2018 19:07:01 +0100 Subject: [PATCH 16/44] Fix formatter tests. --- lib/pleroma/user.ex | 6 +++--- lib/pleroma/user/info.ex | 7 ++++++- test/formatter_test.exs | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 565218b4c..03fe2f1d4 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -87,7 +87,7 @@ def remote_user_creation(params) do info_cng = User.Info.remote_user_creation(%User.Info{}, params[:info]) changes = - %User{info: %{}} + %User{} |> cast(params, [:bio, :name, :ap_id, :nickname, :avatar]) |> validate_required([:name, :ap_id]) |> unique_constraint(:nickname) @@ -718,7 +718,7 @@ def get_or_create_instance_user do user else changes = - %User{info: %{}} + %User{info: %User.Info{}} |> cast(%{}, [:ap_id, :nickname, :local]) |> put_change(:ap_id, relay_uri) |> put_change(:nickname, nil) @@ -763,9 +763,9 @@ def insert_or_update_user(data) do data = data |> Map.put(:name, blank?(data[:name]) || data[:nickname]) - |> Map.put(:info, data[:info] || %{}) cs = User.remote_user_creation(data) + Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname) end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 48f3a4d4a..7d5df34ba 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -89,7 +89,12 @@ def set_keys(info, keys) do def remote_user_creation(info, params) do info - |> cast(params, [:source_data]) + |> cast(params, [ + :ap_enabled, + :source_data, + :banner, + :locked + ]) end # Receives data from user_data_from_user_object diff --git a/test/formatter_test.exs b/test/formatter_test.exs index 13084baa7..e4da84c10 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -110,7 +110,7 @@ test "gives a replacement for user links" do archaeme = insert(:user, %{ nickname: "archaeme", - info: %{"source_data" => %{"url" => "https://archeme/@archaeme"}} + info: %Pleroma.User.Info{source_data: %{"url" => "https://archeme/@archaeme"}} }) archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"}) From 6f0b9a51638e6c2af2aee4d106bc39e03ff7ef2c Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 20 Nov 2018 19:15:28 +0100 Subject: [PATCH 17/44] Fix Notification tests. --- lib/pleroma/web/common_api/common_api.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 77e4dbbd7..e9bad8d04 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -8,7 +8,7 @@ defmodule Pleroma.Web.CommonAPI do def delete(activity_id, user) do with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id), %Object{} = object <- Object.normalize(object_id), - true <- user.info["is_moderator"] || user.ap_id == object.data["actor"], + true <- user.info.is_moderator || user.ap_id == object.data["actor"], {:ok, delete} <- ActivityPub.delete(object) do {:ok, delete} end From 312676f71192889a9d3d1948f8afa53ec32b53e2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 18:41:44 +0000 Subject: [PATCH 18/44] user: fix user.info lookup in User.locked?() --- lib/pleroma/user.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 03fe2f1d4..c7de03347 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -286,7 +286,7 @@ def following?(%User{} = follower, %User{} = followed) do end def locked?(%User{} = user) do - user.info["locked"] || false + user.info.locked || false end def get_by_ap_id(ap_id) do From 4ac849cb4ad1ce10b4d8edd5c371f225c17ce757 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 18:42:28 +0000 Subject: [PATCH 19/44] common api: fix moderator check when deleting posts --- lib/pleroma/web/common_api/common_api.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 77e4dbbd7..e9bad8d04 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -8,7 +8,7 @@ defmodule Pleroma.Web.CommonAPI do def delete(activity_id, user) do with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id), %Object{} = object <- Object.normalize(object_id), - true <- user.info["is_moderator"] || user.ap_id == object.data["actor"], + true <- user.info.is_moderator || user.ap_id == object.data["actor"], {:ok, delete} <- ActivityPub.delete(object) do {:ok, delete} end From 3356c7d1e9c0abd7573768e63e004d51aa0e52b9 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 18:47:00 +0000 Subject: [PATCH 20/44] oauth plug: fix deactivated check --- lib/pleroma/plugs/oauth_plug.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex index 0380ce14d..630f15eec 100644 --- a/lib/pleroma/plugs/oauth_plug.ex +++ b/lib/pleroma/plugs/oauth_plug.ex @@ -20,7 +20,7 @@ def call(conn, _) do with token when not is_nil(token) <- token, %Token{user_id: user_id} <- Repo.get_by(Token, token: token), %User{} = user <- Repo.get(User, user_id), - false <- !!user.info["deactivated"] do + false <- !!user.info.deactivated do conn |> assign(:user, user) else From ece86567335ece6325ebde05995b53735319fbe0 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 18:47:12 +0000 Subject: [PATCH 21/44] streamer: fix fetching the user's block list --- lib/pleroma/web/streamer.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 6b6d40346..209450383 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -173,7 +173,7 @@ def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = ite Enum.each(topics[topic] || [], fn socket -> # Get the current user so we have up-to-date blocks etc. user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) - blocks = user.info["blocks"] || [] + blocks = user.info.blocks || [] parent = Object.normalize(item.data["object"]) @@ -187,7 +187,7 @@ def push_to_socket(topics, topic, item) do Enum.each(topics[topic] || [], fn socket -> # Get the current user so we have up-to-date blocks etc. user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) - blocks = user.info["blocks"] || [] + blocks = user.info.blocks || [] unless item.actor in blocks do send(socket.transport_pid, {:text, represent_update(item, user)}) From c196754b4ddf53a68f42ac26a98c42eeba78a12b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 18:54:48 +0000 Subject: [PATCH 22/44] mastodon api: account view: fix tests --- lib/pleroma/web/mastodon_api/views/account_view.ex | 6 +++--- test/web/mastodon_api/account_view_test.exs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index b68845e16..bcfa8836e 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -14,10 +14,10 @@ def render("account.json", %{user: user} = opts) do image = User.avatar_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) - bot = (user.info["source_data"]["type"] || "Person") in ["Application", "Service"] + bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"] emojis = - (user.info["source_data"]["tag"] || []) + (user.info.source_data["tag"] || []) |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end) |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} -> %{ @@ -29,7 +29,7 @@ def render("account.json", %{user: user} = opts) do end) fields = - (user.info["source_data"]["attachment"] || []) + (user.info.source_data["attachment"] || []) |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end) |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end) diff --git a/test/web/mastodon_api/account_view_test.exs b/test/web/mastodon_api/account_view_test.exs index dc52b92bc..a2d3a2547 100644 --- a/test/web/mastodon_api/account_view_test.exs +++ b/test/web/mastodon_api/account_view_test.exs @@ -17,7 +17,7 @@ test "Represent a user account" do user = insert(:user, %{ - info: %{"note_count" => 5, "follower_count" => 3, "source_data" => source_data}, + info: %{note_count: 5, follower_count: 3, source_data: source_data}, nickname: "shp@shitposter.club", name: ":karjalanpiirakka: shp", bio: "valid html", @@ -63,7 +63,7 @@ test "Represent a user account" do test "Represent a Service(bot) account" do user = insert(:user, %{ - info: %{"note_count" => 5, "follower_count" => 3, "source_data" => %{"type" => "Service"}}, + info: %{note_count: 5, follower_count: 3, source_data: %{"type" => "Service"}}, nickname: "shp@shitposter.club", inserted_at: ~N[2017-08-15 15:47:06.597036] }) From ef6c64a5d24085b05162ebd3a60cf2975386edea Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 18:58:08 +0000 Subject: [PATCH 23/44] activitypub: fix restrict_blocked() --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 54ca891b9..47836ae13 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -509,8 +509,8 @@ defp restrict_recent(query, _) do end defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do - blocks = info["blocks"] || [] - domain_blocks = info["domain_blocks"] || [] + blocks = info.blocks || [] + domain_blocks = info.domain_blocks || [] from( activity in query, From 3456948cd15a14e419abb73a3cb660624b5c32c2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 19:02:23 +0000 Subject: [PATCH 24/44] mastodon api: fix up quite a few test failures --- lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index a0b74311b..280bd78fc 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -659,7 +659,7 @@ def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do # TODO: Use proper query def blocks(%{assigns: %{user: user}} = conn, _) do - with blocked_users <- user.info["blocks"] || [], + with blocked_users <- user.info.blocks || [], accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do res = AccountView.render("accounts.json", users: accounts, for: user, as: :user) json(conn, res) @@ -667,7 +667,7 @@ def blocks(%{assigns: %{user: user}} = conn, _) do end def domain_blocks(%{assigns: %{user: %{info: info}}} = conn, _) do - json(conn, info["domain_blocks"] || []) + json(conn, info.domain_blocks || []) end def block_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do @@ -915,11 +915,11 @@ def index(%{assigns: %{user: user}} = conn, _params) do max_toot_chars: limit }, rights: %{ - delete_others_notice: !!user.info["is_moderator"] + delete_others_notice: !!user.info.is_moderator }, compose: %{ me: "#{user.id}", - default_privacy: user.info["default_scope"] || "public", + default_privacy: user.info.default_scope || "public", default_sensitive: false }, media_attachments: %{ From 5b3480d896ac71e264ffd4ae27fcba9897a81f00 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 20 Nov 2018 19:08:41 +0000 Subject: [PATCH 25/44] tests: fix up some more broken mastodon api testcases --- test/web/mastodon_api/mastodon_api_controller_test.exs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index ad67cae6b..020a2276e 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -252,7 +252,7 @@ test "verify_credentials", %{conn: conn} do end test "verify_credentials default scope unlisted", %{conn: conn} do - user = insert(:user, %{info: %{"default_scope" => "unlisted"}}) + user = insert(:user, %{info: %{default_scope: "unlisted"}}) conn = conn @@ -845,7 +845,7 @@ test "returns the relationships for the current user", %{conn: conn} do describe "locked accounts" do test "/api/v1/follow_requests works" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user, %{info: %{locked: true}}) other_user = insert(:user) {:ok, activity} = ActivityPub.follow(other_user, user) @@ -865,7 +865,7 @@ test "/api/v1/follow_requests works" do end test "/api/v1/follow_requests/:id/authorize works" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user, %{info: %{locked: true}}) other_user = insert(:user) {:ok, activity} = ActivityPub.follow(other_user, user) @@ -890,7 +890,7 @@ test "/api/v1/follow_requests/:id/authorize works" do end test "verify_credentials", %{conn: conn} do - user = insert(:user, %{info: %{"default_scope" => "private"}}) + user = insert(:user, %{info: %{default_scope: "private"}}) conn = conn @@ -902,7 +902,7 @@ test "verify_credentials", %{conn: conn} do end test "/api/v1/follow_requests/:id/reject works" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user, %{info: %{locked: true}}) other_user = insert(:user) {:ok, activity} = ActivityPub.follow(other_user, user) From 0896cf4c0ffacd8e57f5f69f4fb6fe36391c15e8 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 20 Nov 2018 20:12:39 +0100 Subject: [PATCH 26/44] Fix most mastodon api bugs. --- lib/pleroma/user/info.ex | 9 ++- lib/pleroma/web/activity_pub/activity_pub.ex | 6 +- .../web/activity_pub/views/user_view.ex | 8 +-- lib/pleroma/web/common_api/common_api.ex | 7 +- .../mastodon_api/mastodon_api_controller.ex | 64 +++++++++---------- .../web/mastodon_api/views/account_view.ex | 6 +- .../mastodon_api_controller_test.exs | 10 +-- 7 files changed, 57 insertions(+), 53 deletions(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 7d5df34ba..eaf1583e7 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -17,6 +17,7 @@ defmodule Pleroma.User.Info do field(:ap_enabled, :boolean, default: false) field(:is_moderator, :boolean, default: false) field(:keys, :string, default: nil) + field(:settings, :map, default: nil) end def set_activation_status(info, deactivated) do @@ -97,9 +98,11 @@ def remote_user_creation(info, params) do ]) end - # Receives data from user_data_from_user_object - def user_upgrade(info, params) do + def set_source_data(info, source_data) do + params = %{source_data: source_data} + info - |> cast(params, [:ap_enabled, :source_data, :banner, :locked]) + |> cast(params, [:source_data]) + |> validate_required([:source_data]) end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 54ca891b9..5cb350c8d 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -509,8 +509,8 @@ defp restrict_recent(query, _) do end defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do - blocks = info["blocks"] || [] - domain_blocks = info["domain_blocks"] || [] + blocks = info.blocks || [] + domain_blocks = info.domain_blocks || [] from( activity in query, @@ -678,7 +678,7 @@ def publish(actor, activity) do remote_inboxes = (Pleroma.Web.Salmon.remote_users(activity) ++ followers) |> Enum.filter(fn user -> User.ap_enabled?(user) end) - |> Enum.map(fn %{info: %{"source_data" => data}} -> + |> Enum.map(fn %{info: %{source_data: data}} -> (is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"] end) |> Enum.uniq() diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index eb335813d..aaa777602 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -12,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do # the instance itself is not a Person, but instead an Application def render("user.json", %{user: %{nickname: nil} = user}) do {:ok, user} = WebFinger.ensure_keys_present(user) - {:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"]) + {:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_encode([public_key]) @@ -40,7 +40,7 @@ def render("user.json", %{user: %{nickname: nil} = user}) do def render("user.json", %{user: user}) do {:ok, user} = WebFinger.ensure_keys_present(user) - {:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"]) + {:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_encode([public_key]) @@ -55,7 +55,7 @@ def render("user.json", %{user: user}) do "name" => user.name, "summary" => user.bio, "url" => user.ap_id, - "manuallyApprovesFollowers" => user.info["locked"] || false, + "manuallyApprovesFollowers" => user.info.locked, "publicKey" => %{ "id" => "#{user.ap_id}#main-key", "owner" => user.ap_id, @@ -72,7 +72,7 @@ def render("user.json", %{user: user}) do "type" => "Image", "url" => User.banner_url(user) }, - "tag" => user.info["source_data"]["tag"] || [] + "tag" => user.info.source_data["tag"] || [] } |> Map.merge(Utils.make_json_ld_header()) end diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index e9bad8d04..e3385310f 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -135,12 +135,13 @@ def post(user, %{"status" => status} = data) do end end + # Updates the emojis for a user based on their profile def update(user) do user = with emoji <- emoji_from_profile(user), - source_data <- (user.info["source_data"] || %{}) |> Map.put("tag", emoji), - new_info <- Map.put(user.info, "source_data", source_data), - change <- User.info_changeset(user, %{info: new_info}), + source_data <- (user.info.source_data || %{}) |> Map.put("tag", emoji), + info_cng <- Pleroma.User.Info.set_source_data(user.info, source_data), + change <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng), {:ok, user} <- User.update_and_set_cache(change) do user else diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index a0b74311b..bfd0f7ff4 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -71,34 +71,34 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do user end - user = - if banner = params["header"] do - with %Plug.Upload{} <- banner, - {:ok, object} <- ActivityPub.upload(banner, banner_upload_limit), - new_info <- Map.put(user.info, "banner", object.data), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do - user - else - _e -> user - end - else - user - end + # user = + # if banner = params["header"] do + # with %Plug.Upload{} <- banner, + # {:ok, object} <- ActivityPub.upload(banner, banner_upload_limit), + # new_info <- Map.put(user.info, "banner", object.data), + # change <- User.info_changeset(user, %{info: new_info}), + # {:ok, user} <- User.update_and_set_cache(change) do + # user + # else + # _e -> user + # end + # else + # user + # end - user = - if locked = params["locked"] do - with locked <- locked == "true", - new_info <- Map.put(user.info, "locked", locked), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do - user - else - _e -> user - end - else - user - end + # user = + # if locked = params["locked"] do + # with locked <- locked == "true", + # new_info <- Map.put(user.info, "locked", locked), + # change <- User.info_changeset(user, %{info: new_info}), + # {:ok, user} <- User.update_and_set_cache(change) do + # user + # else + # _e -> user + # end + # else + # user + # end with changeset <- User.update_changeset(user, params), {:ok, user} <- User.update_and_set_cache(changeset) do @@ -659,7 +659,7 @@ def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do # TODO: Use proper query def blocks(%{assigns: %{user: user}} = conn, _) do - with blocked_users <- user.info["blocks"] || [], + with blocked_users <- user.info.blocks || [], accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do res = AccountView.render("accounts.json", users: accounts, for: user, as: :user) json(conn, res) @@ -667,7 +667,7 @@ def blocks(%{assigns: %{user: user}} = conn, _) do end def domain_blocks(%{assigns: %{user: %{info: info}}} = conn, _) do - json(conn, info["domain_blocks"] || []) + json(conn, info.domain_blocks || []) end def block_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do @@ -915,11 +915,11 @@ def index(%{assigns: %{user: user}} = conn, _params) do max_toot_chars: limit }, rights: %{ - delete_others_notice: !!user.info["is_moderator"] + delete_others_notice: !!user.info.is_moderator }, compose: %{ me: "#{user.id}", - default_privacy: user.info["default_scope"] || "public", + default_privacy: user.info.default_scope, default_sensitive: false }, media_attachments: %{ @@ -939,7 +939,7 @@ def index(%{assigns: %{user: user}} = conn, _params) do ] }, settings: - Map.get(user.info, "settings") || + Map.get(user.info, :settings) || %{ onboarded: true, home: %{ diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index b68845e16..bcfa8836e 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -14,10 +14,10 @@ def render("account.json", %{user: user} = opts) do image = User.avatar_url(user) |> MediaProxy.url() header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) - bot = (user.info["source_data"]["type"] || "Person") in ["Application", "Service"] + bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"] emojis = - (user.info["source_data"]["tag"] || []) + (user.info.source_data["tag"] || []) |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end) |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} -> %{ @@ -29,7 +29,7 @@ def render("account.json", %{user: user} = opts) do end) fields = - (user.info["source_data"]["attachment"] || []) + (user.info.source_data["attachment"] || []) |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end) |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end) diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index ad67cae6b..8577d1b5b 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -252,7 +252,7 @@ test "verify_credentials", %{conn: conn} do end test "verify_credentials default scope unlisted", %{conn: conn} do - user = insert(:user, %{info: %{"default_scope" => "unlisted"}}) + user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "unlisted"}}) conn = conn @@ -845,7 +845,7 @@ test "returns the relationships for the current user", %{conn: conn} do describe "locked accounts" do test "/api/v1/follow_requests works" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user, %{info: %Pleroma.User.Info{locked: true}}) other_user = insert(:user) {:ok, activity} = ActivityPub.follow(other_user, user) @@ -865,7 +865,7 @@ test "/api/v1/follow_requests works" do end test "/api/v1/follow_requests/:id/authorize works" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user, %{info: %Pleroma.User.Info{locked: true}}) other_user = insert(:user) {:ok, activity} = ActivityPub.follow(other_user, user) @@ -890,7 +890,7 @@ test "/api/v1/follow_requests/:id/authorize works" do end test "verify_credentials", %{conn: conn} do - user = insert(:user, %{info: %{"default_scope" => "private"}}) + user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "private"}}) conn = conn @@ -902,7 +902,7 @@ test "verify_credentials", %{conn: conn} do end test "/api/v1/follow_requests/:id/reject works" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user, %{info: %Pleroma.User.Info{locked: true}}) other_user = insert(:user) {:ok, activity} = ActivityPub.follow(other_user, user) From d3180e0ccc6608c0b3cc8fe552ef52cf2a49d26c Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 20 Nov 2018 20:14:38 +0100 Subject: [PATCH 27/44] Raise on usage of old function. --- lib/pleroma/user.ex | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 03fe2f1d4..d6f61ac46 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -61,9 +61,7 @@ def follow_changeset(struct, params \\ %{}) do end def info_changeset(struct, params \\ %{}) do - struct - |> cast(params, [:info]) - |> validate_required([:info]) + raise "NOT VALID ANYMORE" end def user_info(%User{} = user) do From f983c1d0c6f83f80b06267479646e00421ada543 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 27 Nov 2018 17:31:14 +0100 Subject: [PATCH 28/44] Fix CommonApi tests. --- test/web/common_api/common_api_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index cd36e409c..8fc65f4c0 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -17,7 +17,7 @@ test "it adds emoji when updating profiles" do CommonAPI.update(user) user = User.get_cached_by_ap_id(user.ap_id) - [karjalanpiirakka] = user.info["source_data"]["tag"] + [karjalanpiirakka] = user.info.source_data["tag"] assert karjalanpiirakka["name"] == ":karjalanpiirakka:" end From ec464ef20af289769ea69520e58791777f62554b Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 27 Nov 2018 17:42:45 +0100 Subject: [PATCH 29/44] HTTP sig fixes. --- lib/pleroma/user/info.ex | 10 ++++++++++ lib/pleroma/web/http_signatures/http_signatures.ex | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index eaf1583e7..630e9129a 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -98,6 +98,16 @@ def remote_user_creation(info, params) do ]) end + def user_upgrade(info, params) do + info + |> cast(params, [ + :ap_enabled, + :source_data, + :banner, + :locked + ]) + end + def set_source_data(info, source_data) do params = %{source_data: source_data} diff --git a/lib/pleroma/web/http_signatures/http_signatures.ex b/lib/pleroma/web/http_signatures/http_signatures.ex index 5e42a871b..0e54debd5 100644 --- a/lib/pleroma/web/http_signatures/http_signatures.ex +++ b/lib/pleroma/web/http_signatures/http_signatures.ex @@ -65,7 +65,7 @@ def build_signing_string(headers, used_headers) do end def sign(user, headers) do - with {:ok, %{info: %{"keys" => keys}}} <- Pleroma.Web.WebFinger.ensure_keys_present(user), + with {:ok, %{info: %{keys: keys}}} <- Pleroma.Web.WebFinger.ensure_keys_present(user), {:ok, private_key, _} = Pleroma.Web.Salmon.keys_from_pem(keys) do sigstring = build_signing_string(headers, Map.keys(headers)) From badbe2656c9ac33c35976ae8ebdbd6c305300307 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 27 Nov 2018 18:12:03 +0100 Subject: [PATCH 30/44] More fixes. --- lib/pleroma/user.ex | 5 ++-- lib/pleroma/user/info.ex | 8 ++++-- test/web/activity_pub/activity_pub_test.exs | 4 +-- test/web/activity_pub/transmogrifier_test.exs | 28 +++++++++---------- .../mastodon_api_controller_test.exs | 2 +- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1bf0f568c..bed8fd1b4 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -112,6 +112,7 @@ def remote_user_creation(params) do end end + # TODO: Check if this still used def update_changeset(struct, params \\ %{}) do struct |> cast(params, [:bio, :name]) @@ -730,7 +731,7 @@ def get_or_create_instance_user do # AP style def public_key_from_info(%{ - "source_data" => %{"publicKey" => %{"publicKeyPem" => public_key_pem}} + source_data: %{"publicKey" => %{"publicKeyPem" => public_key_pem}} }) do key = :public_key.pem_decode(public_key_pem) @@ -741,7 +742,7 @@ def public_key_from_info(%{ end # OStatus Magic Key - def public_key_from_info(%{"magic_key" => magic_key}) do + def public_key_from_info(%{magic_key: magic_key}) do {:ok, Pleroma.Web.Salmon.decode_key(magic_key)} end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 630e9129a..a11e50022 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -18,6 +18,8 @@ defmodule Pleroma.User.Info do field(:is_moderator, :boolean, default: false) field(:keys, :string, default: nil) field(:settings, :map, default: nil) + field(:magic_key, :string, default: nil) + # topic, subject, salmon, subscribe_address end def set_activation_status(info, deactivated) do @@ -94,7 +96,8 @@ def remote_user_creation(info, params) do :ap_enabled, :source_data, :banner, - :locked + :locked, + :magic_key ]) end @@ -104,7 +107,8 @@ def user_upgrade(info, params) do :ap_enabled, :source_data, :banner, - :locked + :locked, + :magic_key ]) end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 35c381ac3..1d561d38d 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -14,8 +14,8 @@ test "it returns a user" do {:ok, user} = ActivityPub.make_user_from_ap_id(user_id) assert user.ap_id == user_id assert user.nickname == "admin@mastodon.example.org" - assert user.info["source_data"] - assert user.info["ap_enabled"] + assert user.info.source_data + assert user.info.ap_enabled assert user.follower_address == "http://mastodon.example.org/users/admin/followers" end end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 829da0a65..e74b8f9a1 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -92,7 +92,7 @@ test "it works for incoming notices" do user = User.get_by_ap_id(object["actor"]) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 end test "it works for incoming notices with hashtags" do @@ -307,7 +307,7 @@ test "it works for incoming update activities" do } ] - assert user.info["banner"]["url"] == [ + assert user.info.banner["url"] == [ %{ "href" => "https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png" @@ -337,7 +337,7 @@ test "it works for incoming update activities which lock the account" do {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data) user = User.get_cached_by_ap_id(data["actor"]) - assert user.info["locked"] == true + assert user.info.locked == true end test "it works for incoming deletes" do @@ -543,7 +543,7 @@ test "it works for incoming accepts which were pre-accepted" do test "it works for incoming accepts which were orphaned" do follower = insert(:user) - followed = insert(:user, %{info: %{"locked" => true}}) + followed = insert(:user, %{info: %User.Info{locked: true}}) {:ok, follow_activity} = ActivityPub.follow(follower, followed) @@ -565,7 +565,7 @@ test "it works for incoming accepts which were orphaned" do test "it works for incoming accepts which are referenced by IRI only" do follower = insert(:user) - followed = insert(:user, %{info: %{"locked" => true}}) + followed = insert(:user, %{info: %User.Info{locked: true}}) {:ok, follow_activity} = ActivityPub.follow(follower, followed) @@ -585,7 +585,7 @@ test "it works for incoming accepts which are referenced by IRI only" do test "it fails for incoming accepts which cannot be correlated" do follower = insert(:user) - followed = insert(:user, %{info: %{"locked" => true}}) + followed = insert(:user, %{info: %User.Info{locked: true}}) accept_data = File.read!("test/fixtures/mastodon-accept-activity.json") @@ -604,7 +604,7 @@ test "it fails for incoming accepts which cannot be correlated" do test "it fails for incoming rejects which cannot be correlated" do follower = insert(:user) - followed = insert(:user, %{info: %{"locked" => true}}) + followed = insert(:user, %{info: %User.Info{locked: true}}) accept_data = File.read!("test/fixtures/mastodon-reject-activity.json") @@ -623,7 +623,7 @@ test "it fails for incoming rejects which cannot be correlated" do test "it works for incoming rejects which are orphaned" do follower = insert(:user) - followed = insert(:user, %{info: %{"locked" => true}}) + followed = insert(:user, %{info: %User.Info{locked: true}}) {:ok, follower} = User.follow(follower, followed) {:ok, _follow_activity} = ActivityPub.follow(follower, followed) @@ -648,7 +648,7 @@ test "it works for incoming rejects which are orphaned" do test "it works for incoming rejects which are referenced by IRI only" do follower = insert(:user) - followed = insert(:user, %{info: %{"locked" => true}}) + followed = insert(:user, %{info: %User.Info{locked: true}}) {:ok, follower} = User.follow(follower, followed) {:ok, follow_activity} = ActivityPub.follow(follower, followed) @@ -815,18 +815,18 @@ test "it upgrades a user to activitypub" do assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients user = Repo.get(User, user.id) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye") - assert user.info["ap_enabled"] - assert user.info["note_count"] == 1 + assert user.info.ap_enabled + assert user.info.note_count == 1 assert user.follower_address == "https://niu.moe/users/rye/followers" # Wait for the background task :timer.sleep(1000) user = Repo.get(User, user.id) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 activity = Repo.get(Activity, activity.id) assert user.follower_address in activity.recipients @@ -847,7 +847,7 @@ test "it upgrades a user to activitypub" do "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png" } ] - } = user.info["banner"] + } = user.info.banner refute "..." in activity.recipients diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 8577d1b5b..ef9db20cf 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -1105,7 +1105,7 @@ test "blocking / unblocking a domain", %{conn: conn} do refute User.blocks?(user, other_user) end - test "getting a list of domain blocks" do + test "getting a list of domain blocks", %{conn: conn} do user = insert(:user) {:ok, user} = User.block_domain(user, "bad.site") From 5bd3b3a215bc0b1e55a99a32c799e1273039cb22 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 27 Nov 2018 18:21:05 +0100 Subject: [PATCH 31/44] More and more fixes. --- test/web/node_info_test.exs | 6 +++--- test/web/ostatus/ostatus_controller_test.exs | 16 +++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index a6376453c..a5b0b7869 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -4,7 +4,7 @@ defmodule Pleroma.Web.NodeInfoTest do import Pleroma.Factory test "nodeinfo shows staff accounts", %{conn: conn} do - user = insert(:user, %{local: true, info: %{"is_moderator" => true}}) + user = insert(:user, %{local: true, info: %{is_moderator: true}}) conn = conn @@ -15,7 +15,7 @@ test "nodeinfo shows staff accounts", %{conn: conn} do assert user.ap_id in result["metadata"]["staffAccounts"] end - test "returns 404 when federation is disabled" do + test "returns 404 when federation is disabled", %{conn: conn} do instance = Application.get_env(:pleroma, :instance) |> Keyword.put(:federating, false) @@ -37,7 +37,7 @@ test "returns 404 when federation is disabled" do Application.put_env(:pleroma, :instance, instance) end - test "returns 200 when federation is enabled" do + test "returns 200 when federation is enabled", %{conn: conn} do conn |> get("/.well-known/nodeinfo") |> json_response(200) diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 371c835c0..e81adde68 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -31,14 +31,16 @@ test "decodes a salmon with a changed magic key", %{conn: conn} do # Set a wrong magic-key for a user so it has to refetch salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1") # Wrong key - info = - salmon_user.info - |> Map.put( - "magic_key", - "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB" - ) + info_cng = + User.Info.remote_user_creation(salmon_user.info, %{ + magic_key: + "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB" + }) - Repo.update(User.info_changeset(salmon_user, %{info: info})) + cng = + Ecto.Changeset.change(salmon_user) + |> Ecto.Changeset.put_embed(:info, info_cng) + |> Repo.update() conn = build_conn() From 3c61df6b9ed4f66f0cc6ae6f1e7e167f7bfb2210 Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 27 Nov 2018 18:31:44 +0100 Subject: [PATCH 32/44] Webfinger fixes. --- lib/pleroma/web/web_finger/web_finger.ex | 4 ++-- test/web/web_finger/web_finger_test.exs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 5bf529840..eaee3a8c6 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -45,7 +45,7 @@ def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do def represent_user(user, "JSON") do {:ok, user} = ensure_keys_present(user) - {:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"]) + {:ok, _private, public} = Salmon.keys_from_pem(user.info.keys) magic_key = Salmon.encode_key(public) %{ @@ -83,7 +83,7 @@ def represent_user(user, "JSON") do def represent_user(user, "XML") do {:ok, user} = ensure_keys_present(user) - {:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"]) + {:ok, _private, public} = Salmon.keys_from_pem(user.info.keys) magic_key = Salmon.encode_key(public) { diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs index 99bf210ea..28d429565 100644 --- a/test/web/web_finger/web_finger_test.exs +++ b/test/web/web_finger/web_finger_test.exs @@ -99,15 +99,15 @@ test "it gets the xrd endpoint for statusnet" do describe "ensure_keys_present" do test "it creates keys for a user and stores them in info" do user = insert(:user) - refute is_binary(user.info["keys"]) + refute is_binary(user.info.keys) {:ok, user} = WebFinger.ensure_keys_present(user) - assert is_binary(user.info["keys"]) + assert is_binary(user.info.keys) end test "it doesn't create keys if there already are some" do - user = insert(:user, %{info: %{"keys" => "xxx"}}) + user = insert(:user, %{info: %{keys: "xxx"}}) {:ok, user} = WebFinger.ensure_keys_present(user) - assert user.info["keys"] == "xxx" + assert user.info.keys == "xxx" end end end From e00285807164fab1cf4017db83327ab6cb206f4e Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 27 Nov 2018 18:37:46 +0100 Subject: [PATCH 33/44] Fix ostatus test. --- lib/pleroma/user/info.ex | 6 ++++-- test/web/ostatus/ostatus_test.exs | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index a11e50022..08370fe3c 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -19,7 +19,8 @@ defmodule Pleroma.User.Info do field(:keys, :string, default: nil) field(:settings, :map, default: nil) field(:magic_key, :string, default: nil) - # topic, subject, salmon, subscribe_address + field(:uri, :string, default: nil) + # topic, subject, salmon, subscribe_address, uri end def set_activation_status(info, deactivated) do @@ -97,7 +98,8 @@ def remote_user_creation(info, params) do :source_data, :banner, :locked, - :magic_key + :magic_key, + :uri ]) end diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index f95da8b0a..b2f25d215 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -17,7 +17,7 @@ test "handle incoming note - GS, Salmon" do {:ok, [activity]} = OStatus.handle_incoming(incoming) user = User.get_by_ap_id(activity.data["actor"]) - assert user.info["note_count"] == 1 + assert user.info.note_count == 1 assert activity.data["type"] == "Create" assert activity.data["object"]["type"] == "Note" @@ -319,7 +319,7 @@ test "tries to use the information in poco fields" do assert user.name == "Constance Variable" assert user.nickname == "lambadalambda@social.heldscal.la" assert user.local == false - assert user.info["uri"] == uri + assert user.info.uri == uri assert user.ap_id == uri assert user.bio == "Call me Deacon Blues." assert user.avatar["type"] == "Image" From 6ac5d4857577a5f783273ed5f6bbd6186fcc624d Mon Sep 17 00:00:00 2001 From: lain Date: Thu, 29 Nov 2018 00:25:43 +0100 Subject: [PATCH 34/44] More fixes --- test/web/ostatus/user_representer_test.exs | 2 +- test/web/twitter_api/representers/activity_representer_test.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/web/ostatus/user_representer_test.exs b/test/web/ostatus/user_representer_test.exs index e41dfeb3d..82fb8e793 100644 --- a/test/web/ostatus/user_representer_test.exs +++ b/test/web/ostatus/user_representer_test.exs @@ -6,7 +6,7 @@ defmodule Pleroma.Web.OStatus.UserRepresenterTest do alias Pleroma.User test "returns a user with id, uri, name and link" do - user = build(:user, nickname: "レイン") + user = insert(:user, %{nickname: "レイン"}) tuple = UserRepresenter.to_simple_form(user) res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> to_string diff --git a/test/web/twitter_api/representers/activity_representer_test.exs b/test/web/twitter_api/representers/activity_representer_test.exs index 291fd5237..7cae4e4a1 100644 --- a/test/web/twitter_api/representers/activity_representer_test.exs +++ b/test/web/twitter_api/representers/activity_representer_test.exs @@ -58,7 +58,7 @@ test "a like activity" do end test "an activity" do - {:ok, user} = UserBuilder.insert() + user = insert(:user) # {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"}) mentioned_user = insert(:user, %{nickname: "shp"}) From a6812bc9dff96a600558c534ee24ed176a8eea28 Mon Sep 17 00:00:00 2001 From: lain Date: Fri, 30 Nov 2018 16:47:37 +0100 Subject: [PATCH 35/44] Remove "most recent notification" endpoint. --- lib/pleroma/web/router.ex | 6 ------ .../web/twitter_api/twitter_api_controller.ex | 14 ------------- .../twitter_api_controller_test.exs | 20 ------------------- 3 files changed, 40 deletions(-) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 462369806..a8468ea12 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -265,12 +265,6 @@ defmodule Pleroma.Web.Router do post("/account/update_profile_banner", TwitterAPI.Controller, :update_banner) post("/qvitter/update_background_image", TwitterAPI.Controller, :update_background) - post( - "/account/most_recent_notification", - TwitterAPI.Controller, - :update_most_recent_notification - ) - get("/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline) get("/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline) get("/statuses/mentions", TwitterAPI.Controller, :mentions_timeline) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index cd0e2121c..8a5cf5fcd 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -350,20 +350,6 @@ def external_profile(%{assigns: %{user: current_user}} = conn, %{"profileurl" => end end - def update_most_recent_notification(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with id when is_number(id) <- String.to_integer(id), - info <- user.info, - mrn <- max(id, user.info["most_recent_notification"] || 0), - updated_info <- Map.put(info, "most_recent_notification", mrn), - changeset <- User.info_changeset(user, %{info: updated_info}), - {:ok, _user} <- User.update_and_set_cache(changeset) do - conn - |> json_reply(200, Jason.encode!(mrn)) - else - _e -> bad_request_reply(conn, "Can't update.") - end - end - def followers(conn, params) do with {:ok, user} <- TwitterAPI.get_user(conn.assigns[:user], params), {:ok, followers} <- User.get_followers(user) do diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index 6bdcb4fd8..9062f1c4e 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -31,26 +31,6 @@ test "with credentials", %{conn: conn, user: user} do end end - describe "POST /api/account/most_recent_notification" do - setup [:valid_user] - - test "without valid credentials", %{conn: conn} do - conn = post(conn, "/api/account/most_recent_notification.json") - assert json_response(conn, 403) == %{"error" => "Invalid credentials."} - end - - test "with credentials", %{conn: conn, user: user} do - conn = - conn - |> with_credentials(user.nickname, "test") - |> post("/api/account/most_recent_notification.json", %{id: "200"}) - - assert json_response(conn, 200) - user = User.get_by_nickname(user.nickname) - assert user.info["most_recent_notification"] == 200 - end - end - describe "POST /statuses/update.json" do setup [:valid_user] From d407f662af625818aa1a3d236b354b120546516d Mon Sep 17 00:00:00 2001 From: lain Date: Fri, 30 Nov 2018 17:07:37 +0100 Subject: [PATCH 36/44] Fix TwitterApiController. --- lib/pleroma/user/info.ex | 9 ++ .../web/twitter_api/twitter_api_controller.ex | 101 ++++++++---------- .../twitter_api_controller_test.exs | 14 +-- 3 files changed, 59 insertions(+), 65 deletions(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 08370fe3c..49387163a 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -114,6 +114,15 @@ def user_upgrade(info, params) do ]) end + def profile_update(info, params) do + info + |> cast(params, [ + :locked, + :no_rich_text, + :default_scope + ]) + end + def set_source_data(info, source_data) do params = %{source_data: source_data} diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 8a5cf5fcd..b0bd98dbc 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -437,67 +437,52 @@ def raw_empty_array(conn, _params) do json(conn, []) end + defp build_info_cng(user, params) do + info_params = + ["no_rich_text", "locked"] + |> Enum.reduce(%{}, fn key, res -> + if value = params[key] do + Map.put(res, key, value == "true") + else + res + end + end) + + info_params = + if value = params["default_scope"] do + Map.put(info_params, "default_scope", value) + else + info_params + end + + User.Info.profile_update(user.info, info_params) + end + + defp add_profile_emoji(user, params) do + if bio = params["description"] do + mentions = Formatter.parse_mentions(bio) + tags = Formatter.parse_tags(bio) + + emoji = + (user.info.source_data["tag"] || []) + |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end) + |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} -> + {String.trim(name, ":"), url} + end) + + bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain") + Map.put(params, "bio", bio_html |> Formatter.emojify(emoji)) + else + params + end + end + def update_profile(%{assigns: %{user: user}} = conn, params) do - params = - if bio = params["description"] do - mentions = Formatter.parse_mentions(bio) - tags = Formatter.parse_tags(bio) - - emoji = - (user.info["source_data"]["tag"] || []) - |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end) - |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} -> - {String.trim(name, ":"), url} - end) - - bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain") - Map.put(params, "bio", bio_html |> Formatter.emojify(emoji)) - else - params - end - - user = - if locked = params["locked"] do - with locked <- locked == "true", - new_info <- Map.put(user.info, "locked", locked), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do - user - else - _e -> user - end - else - user - end - - user = - if no_rich_text = params["no_rich_text"] do - with no_rich_text <- no_rich_text == "true", - new_info <- Map.put(user.info, "no_rich_text", no_rich_text), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do - user - else - _e -> user - end - else - user - end - - user = - if default_scope = params["default_scope"] do - with new_info <- Map.put(user.info, "default_scope", default_scope), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do - user - else - _e -> user - end - else - user - end + params = add_profile_emoji(user, params) + info_cng = build_info_cng(user, params) with changeset <- User.update_changeset(user, params), + changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng), {:ok, user} <- User.update_and_set_cache(changeset) do CommonAPI.update(user) render(conn, UserView, "user.json", %{user: user, for: user}) diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index 9062f1c4e..a76112e37 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -67,7 +67,7 @@ test "with credentials", %{conn: conn, user: user} do describe "GET /statuses/public_timeline.json" do test "returns statuses", %{conn: conn} do - {:ok, user} = UserBuilder.insert() + user = insert(:user) activities = ActivityBuilder.insert_list(30, %{}, %{user: user}) ActivityBuilder.insert_list(10, %{}, %{user: user}) since_id = List.last(activities).id @@ -571,7 +571,7 @@ test "with credentials", %{conn: conn, user: current_user} do |> post("/api/blocks/destroy.json", %{user_id: blocked.id}) current_user = Repo.get(User, current_user.id) - assert current_user.info["blocks"] == [] + assert current_user.info.blocks == [] assert json_response(conn, 200) == UserView.render("show.json", %{user: blocked, for: current_user}) @@ -946,7 +946,7 @@ test "it locks an account", %{conn: conn} do }) user = Repo.get!(User, user.id) - assert user.info["locked"] == true + assert user.info.locked == true assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) end @@ -962,7 +962,7 @@ test "it unlocks an account", %{conn: conn} do }) user = Repo.get!(User, user.id) - assert user.info["locked"] == false + assert user.info.locked == false assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) end @@ -1136,7 +1136,7 @@ test "it lists friend requests" do user = insert(:user, %{info: %{"locked" => true}}) other_user = insert(:user) - {:ok, activity} = ActivityPub.follow(other_user, user) + {:ok, _activity} = ActivityPub.follow(other_user, user) user = Repo.get(User, user.id) other_user = Repo.get(User, other_user.id) @@ -1158,7 +1158,7 @@ test "it approves a friend request" do user = insert(:user, %{info: %{"locked" => true}}) other_user = insert(:user) - {:ok, activity} = ActivityPub.follow(other_user, user) + {:ok, _activity} = ActivityPub.follow(other_user, user) user = Repo.get(User, user.id) other_user = Repo.get(User, other_user.id) @@ -1181,7 +1181,7 @@ test "it denies a friend request" do user = insert(:user, %{info: %{"locked" => true}}) other_user = insert(:user) - {:ok, activity} = ActivityPub.follow(other_user, user) + {:ok, _activity} = ActivityPub.follow(other_user, user) user = Repo.get(User, user.id) other_user = Repo.get(User, other_user.id) From 48b95a9b954b6d9e1b6f98097b35fcca4172c8a0 Mon Sep 17 00:00:00 2001 From: lain Date: Fri, 30 Nov 2018 17:08:02 +0100 Subject: [PATCH 37/44] Assorted fixes. --- lib/pleroma/user/info.ex | 6 +++++- lib/pleroma/web/websub/websub.ex | 4 ++-- test/web/ostatus/ostatus_test.exs | 2 +- test/web/twitter_api/views/user_view_test.exs | 20 +++++++++---------- test/web/websub/websub_test.exs | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 49387163a..4e2c5472d 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -20,6 +20,8 @@ defmodule Pleroma.User.Info do field(:settings, :map, default: nil) field(:magic_key, :string, default: nil) field(:uri, :string, default: nil) + field(:topic, :string, default: nil) + field(:hub, :string, default: nil) # topic, subject, salmon, subscribe_address, uri end @@ -99,7 +101,9 @@ def remote_user_creation(info, params) do :banner, :locked, :magic_key, - :uri + :uri, + :hub, + :topic ]) end diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex index e494811f9..440b48665 100644 --- a/lib/pleroma/web/websub/websub.ex +++ b/lib/pleroma/web/websub/websub.ex @@ -146,7 +146,7 @@ defp valid_topic(%{"hub.topic" => topic}, user) do end def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do - topic = subscribed.info["topic"] + topic = subscribed.info.topic # FIXME: Race condition, use transactions {:ok, subscription} = with subscription when not is_nil(subscription) <- @@ -158,7 +158,7 @@ def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do _e -> subscription = %WebsubClientSubscription{ topic: topic, - hub: subscribed.info["hub"], + hub: subscribed.info.hub, subscribers: [subscriber.ap_id], state: "requested", secret: :crypto.strong_rand_bytes(8) |> Base.url_encode64(), diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index b2f25d215..6e5263014 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -447,7 +447,7 @@ test "it works for atom notes, too" do end end - test "it doesn't add nil in the do field" do + test "it doesn't add nil in the to field" do incoming = File.read!("test/fixtures/nil_mention_entry.xml") {:ok, [activity]} = OStatus.handle_incoming(incoming) diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs index 2c583c0d3..e69ca24a9 100644 --- a/test/web/twitter_api/views/user_view_test.exs +++ b/test/web/twitter_api/views/user_view_test.exs @@ -31,10 +31,10 @@ test "A user with emoji in username", %{user: user} do expected = "\"karjalanpiirakka\" man" - user = %{ - user - | info: %{ - "source_data" => %{ + user = + insert(:user, %{ + info: %{ + source_data: %{ "tag" => [ %{ "type" => "Emoji", @@ -43,10 +43,10 @@ test "A user with emoji in username", %{user: user} do } ] } - } - } + }, + name: ":karjalanpiirakka: man" + }) - user = %{user | name: ":karjalanpiirakka: man"} represented = UserView.render("show.json", %{user: user}) assert represented["name_html"] == expected end @@ -103,7 +103,7 @@ test "A user" do end test "A user for a given other follower", %{user: user} do - {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]}) + follower = insert(:user, %{following: [User.ap_followers(user)]}) {:ok, user} = User.update_follower_count(user) image = "http://localhost:4001/images/avi.png" banner = "http://localhost:4001/images/banner.png" @@ -186,7 +186,7 @@ test "A user that follows you", %{user: user} do end test "a user that is a moderator" do - user = insert(:user, %{info: %{"is_moderator" => true}}) + user = insert(:user, %{info: %{is_moderator: true}}) represented = UserView.render("show.json", %{user: user, for: user}) assert represented["rights"]["delete_others_notice"] @@ -250,7 +250,7 @@ test "a user with mastodon fields" do user = insert(:user, %{ info: %{ - "source_data" => %{ + source_data: %{ "attachment" => Enum.map(fields, fn field -> Map.put(field, "type", "PropertyValue") end) } diff --git a/test/web/websub/websub_test.exs b/test/web/websub/websub_test.exs index 5914a37fc..da7bc9112 100644 --- a/test/web/websub/websub_test.exs +++ b/test/web/websub/websub_test.exs @@ -99,7 +99,7 @@ def accepting_verifier(subscription) do test "initiate a subscription for a given user and topic" do subscriber = insert(:user) - user = insert(:user, %{info: %{"topic" => "some_topic", "hub" => "some_hub"}}) + user = insert(:user, %{info: %Pleroma.User.Info{topic: "some_topic", hub: "some_hub"}}) {:ok, websub} = Websub.subscribe(subscriber, user, &accepting_verifier/1) assert websub.subscribers == [subscriber.ap_id] From d088ac628654a189260279a9216ddb22ab7e56c6 Mon Sep 17 00:00:00 2001 From: lain Date: Fri, 30 Nov 2018 17:21:58 +0100 Subject: [PATCH 38/44] Fix OStatus user updates. Breaks banner updating. --- lib/pleroma/web/ostatus/ostatus.ex | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index 1d0019d3b..6a27f1730 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -226,25 +226,21 @@ def maybe_update_ostatus(doc, user) do old_data = %{ avatar: user.avatar, bio: user.bio, - name: user.name, - info: user.info + name: user.name } with false <- user.local, avatar <- make_avatar_object(doc), bio <- string_from_xpath("//author[1]/summary", doc), name <- string_from_xpath("//author[1]/poco:displayName", doc), - info <- - Map.put(user.info, "banner", make_avatar_object(doc, "header") || user.info["banner"]), new_data <- %{ avatar: avatar || old_data.avatar, name: name || old_data.name, - bio: bio || old_data.bio, - info: info || old_data.info + bio: bio || old_data.bio }, false <- new_data == old_data do change = Ecto.Changeset.change(user, new_data) - Repo.update(change) + User.update_and_set_cache(change) else _ -> {:ok, user} From 8f1fffebc6796f2e0758a99d032ab3db7f2f6e0b Mon Sep 17 00:00:00 2001 From: lain Date: Fri, 30 Nov 2018 17:31:05 +0100 Subject: [PATCH 39/44] Fix transmogrifier test. --- lib/pleroma/web/activity_pub/transmogrifier.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 2d11c40c5..17b063609 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -447,7 +447,7 @@ def handle_incoming( update_data = new_user_data |> Map.take([:name, :bio, :avatar]) - |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner, "locked" => locked})) + |> Map.put(:info, %{"banner" => banner, "locked" => locked}) actor |> User.upgrade_changeset(update_data) From 1c67277c8031be2212d6faf84c143ac11462c87b Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 1 Dec 2018 09:03:16 +0100 Subject: [PATCH 40/44] Fix admin api. --- lib/pleroma/plugs/user_is_admin_plug.ex | 2 +- lib/pleroma/user/info.ex | 9 +++++ .../web/admin_api/admin_api_controller.ex | 27 +++++++++---- test/plugs/user_is_admin_plug_test.exs | 2 +- .../admin_api/admin_api_controller_test.exs | 39 +++++++++---------- 5 files changed, 50 insertions(+), 29 deletions(-) diff --git a/lib/pleroma/plugs/user_is_admin_plug.ex b/lib/pleroma/plugs/user_is_admin_plug.ex index 5312f1499..cf22ce5d0 100644 --- a/lib/pleroma/plugs/user_is_admin_plug.ex +++ b/lib/pleroma/plugs/user_is_admin_plug.ex @@ -6,7 +6,7 @@ def init(options) do options end - def call(%{assigns: %{user: %User{info: %{"is_admin" => true}}}} = conn, _) do + def call(%{assigns: %{user: %User{info: %{is_admin: true}}}} = conn, _) do conn end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 4e2c5472d..a5ce6010f 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -16,6 +16,7 @@ defmodule Pleroma.User.Info do field(:no_rich_text, :boolean, default: false) field(:ap_enabled, :boolean, default: false) field(:is_moderator, :boolean, default: false) + field(:is_admin, :boolean, default: false) field(:keys, :string, default: nil) field(:settings, :map, default: nil) field(:magic_key, :string, default: nil) @@ -134,4 +135,12 @@ def set_source_data(info, source_data) do |> cast(params, [:source_data]) |> validate_required([:source_data]) end + + def admin_api_update(info, params) do + info + |> cast(params, [ + :is_moderator, + :is_admin + ]) + end end diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index bcdb4ba37..2c67d9cda 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -45,21 +45,29 @@ def right_add(conn, %{"permission_group" => permission_group, "nickname" => nick user = User.get_by_nickname(nickname) info = - user.info + %{} |> Map.put("is_" <> permission_group, true) - cng = User.info_changeset(user, %{info: info}) + info_cng = User.Info.admin_api_update(user.info, info) + + cng = + Ecto.Changeset.change(user) + |> Ecto.Changeset.put_embed(:info, info_cng) + {:ok, user} = User.update_and_set_cache(cng) conn - |> json(user.info) + |> json(info) end def right_get(conn, %{"nickname" => nickname}) do user = User.get_by_nickname(nickname) conn - |> json(user.info) + |> json(%{ + is_moderator: user.info.is_moderator, + is_admin: user.info.is_admin + }) end def right_add(conn, _) do @@ -84,14 +92,19 @@ def right_delete( user = User.get_by_nickname(nickname) info = - user.info + %{} |> Map.put("is_" <> permission_group, false) - cng = User.info_changeset(user, %{info: info}) + info_cng = User.Info.admin_api_update(user.info, info) + + cng = + Ecto.Changeset.change(user) + |> Ecto.Changeset.put_embed(:info, info_cng) + {:ok, user} = User.update_and_set_cache(cng) conn - |> json(user.info) + |> json(info) end end diff --git a/test/plugs/user_is_admin_plug_test.exs b/test/plugs/user_is_admin_plug_test.exs index ddf9eb139..031b2f466 100644 --- a/test/plugs/user_is_admin_plug_test.exs +++ b/test/plugs/user_is_admin_plug_test.exs @@ -5,7 +5,7 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do import Pleroma.Factory test "accepts a user that is admin", %{conn: conn} do - user = insert(:user, info: %{"is_admin" => true}) + user = insert(:user, info: %{is_admin: true}) conn = build_conn() diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index fa0cb71bf..9634ad7c5 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "/api/pleroma/admin/user" do test "Delete" do - admin = insert(:user, info: %{"is_admin" => true}) + admin = insert(:user, info: %{is_admin: true}) user = insert(:user) conn = @@ -21,7 +21,7 @@ test "Delete" do end test "Create" do - admin = insert(:user, info: %{"is_admin" => true}) + admin = insert(:user, info: %{is_admin: true}) conn = build_conn() @@ -39,7 +39,7 @@ test "Create" do describe "/api/pleroma/admin/permission_group" do test "GET is giving user_info" do - admin = insert(:user, info: %{"is_admin" => true}) + admin = insert(:user, info: %{is_admin: true}) conn = build_conn() @@ -47,33 +47,30 @@ test "GET is giving user_info" do |> put_req_header("accept", "application/json") |> get("/api/pleroma/admin/permission_group/#{admin.nickname}") - assert json_response(conn, 200) == admin.info + assert json_response(conn, 200) == %{ + "is_admin" => true, + "is_moderator" => false + } end test "/:right POST, can add to a permission group" do - admin = insert(:user, info: %{"is_admin" => true}) + admin = insert(:user, info: %{is_admin: true}) user = insert(:user) - user_info = - user.info - |> Map.put("is_admin", true) - conn = build_conn() |> assign(:user, admin) |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/permission_group/#{user.nickname}/admin") - assert json_response(conn, 200) == user_info + assert json_response(conn, 200) == %{ + "is_admin" => true + } end test "/:right DELETE, can remove from a permission group" do - admin = insert(:user, info: %{"is_admin" => true}) - user = insert(:user, info: %{"is_admin" => true}) - - user_info = - user.info - |> Map.put("is_admin", false) + admin = insert(:user, info: %{is_admin: true}) + user = insert(:user, info: %{is_admin: true}) conn = build_conn() @@ -81,12 +78,14 @@ test "/:right DELETE, can remove from a permission group" do |> put_req_header("accept", "application/json") |> delete("/api/pleroma/admin/permission_group/#{user.nickname}/admin") - assert json_response(conn, 200) == user_info + assert json_response(conn, 200) == %{ + "is_admin" => false + } end end test "/api/pleroma/admin/invite_token" do - admin = insert(:user, info: %{"is_admin" => true}) + admin = insert(:user, info: %{is_admin: true}) conn = build_conn() @@ -98,8 +97,8 @@ test "/api/pleroma/admin/invite_token" do end test "/api/pleroma/admin/password_reset" do - admin = insert(:user, info: %{"is_admin" => true}) - user = insert(:user, info: %{"is_admin" => true}) + admin = insert(:user, info: %{is_admin: true}) + user = insert(:user) conn = build_conn() From 347df6421d6b1794a39ac6ce9e24a9e51e136a62 Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 1 Dec 2018 10:40:01 +0100 Subject: [PATCH 41/44] Fix masto api user updating. --- lib/pleroma/user.ex | 3 +- lib/pleroma/user/info.ex | 8 ++ .../mastodon_api/mastodon_api_controller.ex | 94 ++++++++----------- .../mastodon_api_controller_test.exs | 20 +++- 4 files changed, 66 insertions(+), 59 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index bed8fd1b4..a84ab6841 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -112,10 +112,9 @@ def remote_user_creation(params) do end end - # TODO: Check if this still used def update_changeset(struct, params \\ %{}) do struct - |> cast(params, [:bio, :name]) + |> cast(params, [:bio, :name, :avatar]) |> unique_constraint(:nickname) |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/) |> validate_length(:bio, max: 5000) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index a5ce6010f..8a938e514 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -128,6 +128,14 @@ def profile_update(info, params) do ]) end + def mastodon_profile_update(info, params) do + info + |> cast(params, [ + :locked, + :banner + ]) + end + def set_source_data(info, source_data) do params = %{source_data: source_data} diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index f209bb43c..d19d55044 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -32,67 +32,55 @@ def create_app(conn, params) do end end + defp add_if_present( + map, + params, + params_field, + map_field, + value_function \\ fn x -> {:ok, x} end + ) do + if Map.has_key?(params, params_field) do + case value_function.(params[params_field]) do + {:ok, new_value} -> Map.put(map, map_field, new_value) + :error -> map + end + else + map + end + end + def update_credentials(%{assigns: %{user: user}} = conn, params) do original_user = user - params = - if bio = params["note"] do - Map.put(params, "bio", bio) - else - params - end - - params = - if name = params["display_name"] do - Map.put(params, "name", name) - else - params - end - - user = - if avatar = params["avatar"] do - with %Plug.Upload{} <- avatar, - {:ok, object} <- ActivityPub.upload(avatar, type: :avatar), - change = Ecto.Changeset.change(user, %{avatar: object.data}), - {:ok, user} = User.update_and_set_cache(change) do - user + user_params = + %{} + |> add_if_present(params, "display_name", :name) + |> add_if_present(params, "note", :bio) + |> add_if_present(params, "avatar", :avatar, fn value -> + with %Plug.Upload{} <- value, + {:ok, object} <- ActivityPub.upload(value, type: :avatar) do + {:ok, object.data} else - _e -> user + _ -> :error end - else - user - end + end) - # user = - # if banner = params["header"] do - # with %Plug.Upload{} <- banner, - # {:ok, object} <- ActivityPub.upload(banner, type: :banner), - # new_info <- Map.put(user.info, "banner", object.data), - # change <- User.info_changeset(user, %{info: new_info}), - # {:ok, user} <- User.update_and_set_cache(change) do - # user - # else - # _e -> user - # end - # else - # user - # end + info_params = + %{} + |> add_if_present(params, "locked", :locked, fn value -> {:ok, value == "true"} end) + |> add_if_present(params, "header", :banner, fn value -> + with %Plug.Upload{} <- value, + {:ok, object} <- ActivityPub.upload(value, type: :banner) do + {:ok, object.data} + else + _ -> :error + end + end) - # user = - # if locked = params["locked"] do - # with locked <- locked == "true", - # new_info <- Map.put(user.info, "locked", locked), - # change <- User.info_changeset(user, %{info: new_info}), - # {:ok, user} <- User.update_and_set_cache(change) do - # user - # else - # _e -> user - # end - # else - # user - # end + info_cng = User.Info.mastodon_profile_update(user.info, info_params) - with changeset <- User.update_changeset(user, params), + with changeset <- User.update_changeset(user, user_params), + changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng), {:ok, user} <- User.update_and_set_cache(changeset) do if original_user != user do CommonAPI.update(user) diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index ef9db20cf..7042a6ace 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -1263,6 +1263,18 @@ test "updates the user's bio", %{conn: conn} do assert user["note"] == "I drink #cofe" end + test "updates the user's locking status", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{locked: "true"}) + + assert user = json_response(conn, 200) + assert user["locked"] == true + end + test "updates the user's name", %{conn: conn} do user = insert(:user) @@ -1289,8 +1301,8 @@ test "updates the user's avatar", %{conn: conn} do |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar}) - assert user = json_response(conn, 200) - assert user["avatar"] != "https://placehold.it/48x48" + assert user_response = json_response(conn, 200) + assert user_response["avatar"] != User.avatar_url(user) end test "updates the user's banner", %{conn: conn} do @@ -1307,8 +1319,8 @@ test "updates the user's banner", %{conn: conn} do |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{"header" => new_header}) - assert user = json_response(conn, 200) - assert user["header"] != "https://placehold.it/700x335" + assert user_response = json_response(conn, 200) + assert user_response["header"] != User.banner_url(user) end end From 4996fb07d829a5c93fe97a6f3364f3032fb2c1bb Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 1 Dec 2018 12:00:33 +0100 Subject: [PATCH 42/44] Genereate uuids for existing info fields. --- priv/repo/migrations/20181201104428_add_uuid_extension.exs | 7 +++++++ .../migrations/20181201105617_add_uui_ds_to_user_info.exs | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 priv/repo/migrations/20181201104428_add_uuid_extension.exs create mode 100644 priv/repo/migrations/20181201105617_add_uui_ds_to_user_info.exs diff --git a/priv/repo/migrations/20181201104428_add_uuid_extension.exs b/priv/repo/migrations/20181201104428_add_uuid_extension.exs new file mode 100644 index 000000000..2509e558d --- /dev/null +++ b/priv/repo/migrations/20181201104428_add_uuid_extension.exs @@ -0,0 +1,7 @@ +defmodule Pleroma.Repo.Migrations.AddUUIDExtension do + use Ecto.Migration + + def change do + execute("create extension if not exists \"uuid-ossp\"") + end +end diff --git a/priv/repo/migrations/20181201105617_add_uui_ds_to_user_info.exs b/priv/repo/migrations/20181201105617_add_uui_ds_to_user_info.exs new file mode 100644 index 000000000..9571a1e4d --- /dev/null +++ b/priv/repo/migrations/20181201105617_add_uui_ds_to_user_info.exs @@ -0,0 +1,7 @@ +defmodule Pleroma.Repo.Migrations.AddUUIDsToUserInfo do + use Ecto.Migration + + def change do + execute("update users set info = jsonb_set(info, '{\"id\"}', to_jsonb(uuid_generate_v4()))") + end +end From 93f2dc19d99375356d986651490cb9f496f18928 Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 1 Dec 2018 12:00:53 +0100 Subject: [PATCH 43/44] TwitterAPI: Fix banner and background update. --- lib/pleroma/user/info.ex | 16 ++++++++-- .../web/twitter_api/twitter_api_controller.ex | 14 +++++---- .../twitter_api_controller_test.exs | 30 +++++++++++++++++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 8a938e514..284645934 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -23,7 +23,18 @@ defmodule Pleroma.User.Info do field(:uri, :string, default: nil) field(:topic, :string, default: nil) field(:hub, :string, default: nil) - # topic, subject, salmon, subscribe_address, uri + + # Found in the wild + # ap_id -> Where is this used? + # bio -> Where is this used? + # avatar -> Where is this used? + # fqn -> Where is this used? + # host -> Where is this used? + # name -> Where is this used? + # nickname -> Where is this used? + # salmon -> Where is this used? + # subject _> Where is this used? + # subscribe_address -> Where is this used? end def set_activation_status(info, deactivated) do @@ -124,7 +135,8 @@ def profile_update(info, params) do |> cast(params, [ :locked, :no_rich_text, - :default_scope + :default_scope, + :banner ]) end diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 8f9d6c905..ff644dd79 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -300,9 +300,10 @@ def update_avatar(%{assigns: %{user: user}} = conn, params) do def update_banner(%{assigns: %{user: user}} = conn, params) do with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner), - new_info <- Map.put(user.info, "banner", object.data), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, user} <- User.update_and_set_cache(change) do + new_info <- %{"banner" => object.data}, + info_cng <- User.Info.profile_update(user.info, new_info), + changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng), + {:ok, user} <- User.update_and_set_cache(changeset) do CommonAPI.update(user) %{"url" => [%{"href" => href} | _]} = object.data response = %{url: href} |> Jason.encode!() @@ -314,9 +315,10 @@ def update_banner(%{assigns: %{user: user}} = conn, params) do def update_background(%{assigns: %{user: user}} = conn, params) do with {:ok, object} <- ActivityPub.upload(params, type: :background), - new_info <- Map.put(user.info, "background", object.data), - change <- User.info_changeset(user, %{info: new_info}), - {:ok, _user} <- User.update_and_set_cache(change) do + new_info <- %{"background" => object.data}, + info_cng <- User.Info.profile_update(user.info, new_info), + changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng), + {:ok, _user} <- User.update_and_set_cache(changeset) do %{"url" => [%{"href" => href} | _]} = object.data response = %{url: href} |> Jason.encode!() diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index a76112e37..f7c6e6187 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -12,6 +12,36 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do import Pleroma.Factory + describe "POST /api/account/update_profile_banner" do + test "it updates the banner", %{conn: conn} do + user = insert(:user) + + new_banner = + "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" + + response = + conn + |> assign(:user, user) + |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => new_banner}) + |> json_response(200) + end + end + + describe "POST /api/qvitter/update_background_image" do + test "it updates the background", %{conn: conn} do + user = insert(:user) + + new_bg = + "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" + + response = + conn + |> assign(:user, user) + |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => new_bg}) + |> json_response(200) + end + end + describe "POST /api/account/verify_credentials" do setup [:valid_user] From f18b86fd5f01653dd6e860b2d67021bdce684d6d Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 1 Dec 2018 12:46:08 +0100 Subject: [PATCH 44/44] More fixes for Info schema. --- lib/pleroma/plugs/user_enabled_plug.ex | 2 +- lib/pleroma/user.ex | 2 +- lib/pleroma/user/info.ex | 8 ++--- lib/pleroma/web/salmon/salmon.ex | 4 +-- test/plugs/user_enabled_plug_test.exs | 2 +- test/user_test.exs | 2 +- test/web/ostatus/ostatus_test.exs | 32 +++++++++++++++++++ .../twitter_api_controller_test.exs | 6 ++-- 8 files changed, 44 insertions(+), 14 deletions(-) diff --git a/lib/pleroma/plugs/user_enabled_plug.ex b/lib/pleroma/plugs/user_enabled_plug.ex index 9c3285896..01482f47d 100644 --- a/lib/pleroma/plugs/user_enabled_plug.ex +++ b/lib/pleroma/plugs/user_enabled_plug.ex @@ -6,7 +6,7 @@ def init(options) do options end - def call(%{assigns: %{user: %User{info: %{"deactivated" => true}}}} = conn, _) do + def call(%{assigns: %{user: %User{info: %{deactivated: true}}}} = conn, _) do conn |> assign(:user, nil) end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index a84ab6841..76712b4bf 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -682,7 +682,7 @@ def delete(%User{} = user) do {:ok, user} end - def html_filter_policy(%User{info: %{"no_rich_text" => true}}) do + def html_filter_policy(%User{info: %{no_rich_text: true}}) do Pleroma.HTML.Scrubber.TwitterText end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 284645934..94d403bf7 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -23,6 +23,7 @@ defmodule Pleroma.User.Info do field(:uri, :string, default: nil) field(:topic, :string, default: nil) field(:hub, :string, default: nil) + field(:salmon, :string, default: nil) # Found in the wild # ap_id -> Where is this used? @@ -30,11 +31,7 @@ defmodule Pleroma.User.Info do # avatar -> Where is this used? # fqn -> Where is this used? # host -> Where is this used? - # name -> Where is this used? - # nickname -> Where is this used? - # salmon -> Where is this used? # subject _> Where is this used? - # subscribe_address -> Where is this used? end def set_activation_status(info, deactivated) do @@ -115,7 +112,8 @@ def remote_user_creation(info, params) do :magic_key, :uri, :hub, - :topic + :topic, + :salmon ]) end diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex index 562ec3d9c..b98ece6c9 100644 --- a/lib/pleroma/web/salmon/salmon.ex +++ b/lib/pleroma/web/salmon/salmon.ex @@ -157,7 +157,7 @@ def remote_users(%{data: %{"to" => to} = data}) do |> Enum.filter(fn user -> user && !user.local end) end - defp send_to_user(%{info: %{"salmon" => salmon}}, feed, poster) do + defp send_to_user(%{info: %{salmon: salmon}}, feed, poster) do with {:ok, %{status_code: code}} <- poster.( salmon, @@ -185,7 +185,7 @@ defp send_to_user(_, _, _), do: nil ] def publish(user, activity, poster \\ &@httpoison.post/4) - def publish(%{info: %{"keys" => keys}} = user, %{data: %{"type" => type}} = activity, poster) + def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity, poster) when type in @supported_activities do feed = ActivityRepresenter.to_simple_form(activity, user, true) diff --git a/test/plugs/user_enabled_plug_test.exs b/test/plugs/user_enabled_plug_test.exs index ee4f72ccf..eeb167933 100644 --- a/test/plugs/user_enabled_plug_test.exs +++ b/test/plugs/user_enabled_plug_test.exs @@ -13,7 +13,7 @@ test "doesn't do anything if the user isn't set", %{conn: conn} do end test "with a user that is deactivated, it removes that user", %{conn: conn} do - user = insert(:user, info: %{"deactivated" => true}) + user = insert(:user, info: %{deactivated: true}) conn = conn diff --git a/test/user_test.exs b/test/user_test.exs index f345f001f..62104df90 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -548,7 +548,7 @@ test "html_filter_policy returns nil when rich-text is enabled" do end test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do - user = insert(:user, %{info: %{"no_rich_text" => true}}) + user = insert(:user, %{info: %{no_rich_text: true}}) assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user) end diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index 6e5263014..baa8cac72 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -329,6 +329,38 @@ test "tries to use the information in poco fields" do assert user == user_again end + test "find_or_make_user sets all the nessary input fields" do + uri = "https://social.heldscal.la/user/23211" + {:ok, user} = OStatus.find_or_make_user(uri) + + assert user.info == + %Pleroma.User.Info{ + id: user.info.id, + ap_enabled: false, + background: nil, + banner: %{}, + blocks: [], + deactivated: false, + default_scope: "public", + domain_blocks: [], + follower_count: 0, + is_admin: false, + is_moderator: false, + keys: nil, + locked: false, + no_rich_text: false, + note_count: 0, + settings: nil, + source_data: %{}, + hub: "https://social.heldscal.la/main/push/hub", + magic_key: + "RSA.uzg6r1peZU0vXGADWxGJ0PE34WvmhjUmydbX5YYdOiXfODVLwCMi1umGoqUDm-mRu4vNEdFBVJU1CpFA7dKzWgIsqsa501i2XqElmEveXRLvNRWFB6nG03Q5OUY2as8eE54BJm0p20GkMfIJGwP6TSFb-ICp3QjzbatuSPJ6xCE=.AQAB", + salmon: "https://social.heldscal.la/main/salmon/user/23211", + topic: "https://social.heldscal.la/api/statuses/user_timeline/23211.atom", + uri: "https://social.heldscal.la/user/23211" + } + end + test "find_make_or_update_user takes an author element and returns an updated user" do uri = "https://social.heldscal.la/user/23211" diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index f7c6e6187..89c176da7 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -1163,7 +1163,7 @@ test "with credentials and valid password", %{conn: conn, user: current_user} do describe "GET /api/pleroma/friend_requests" do test "it lists friend requests" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user) other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user) @@ -1185,7 +1185,7 @@ test "it lists friend requests" do describe "POST /api/pleroma/friendships/approve" do test "it approves a friend request" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user) other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user) @@ -1208,7 +1208,7 @@ test "it approves a friend request" do describe "POST /api/pleroma/friendships/deny" do test "it denies a friend request" do - user = insert(:user, %{info: %{"locked" => true}}) + user = insert(:user) other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user)