From 3208611bfc9c8edfeab3ab4bbce5b6e0ad0bf9e6 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 26 May 2018 14:45:41 +0000 Subject: [PATCH 01/24] mix: add task for setting an account as locked or not --- lib/mix/tasks/set_locked.ex | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lib/mix/tasks/set_locked.ex diff --git a/lib/mix/tasks/set_locked.ex b/lib/mix/tasks/set_locked.ex new file mode 100644 index 000000000..2b3b18b09 --- /dev/null +++ b/lib/mix/tasks/set_locked.ex @@ -0,0 +1,30 @@ +defmodule Mix.Tasks.SetLocked do + use Mix.Task + import Mix.Ecto + alias Pleroma.{Repo, User} + + @shortdoc "Set locked status" + def run([nickname | rest]) do + ensure_started(Repo, []) + + locked = + case rest do + [locked] -> locked == "true" + _ -> true + end + + with %User{local: true} = user <- User.get_by_nickname(nickname) do + info = + user.info + |> Map.put("locked", !!locked) + + cng = User.info_changeset(user, %{info: info}) + user = Repo.update!(cng) + + IO.puts("locked status of #{nickname}: #{user.info["locked"]}") + else + _ -> + IO.puts("No local user #{nickname}") + end + end +end From e5206752e163affc3c0b7bca506e89a6249f5702 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 26 May 2018 14:55:16 +0000 Subject: [PATCH 02/24] activitypub: only send accept back automatically if the account is not locked --- lib/pleroma/user.ex | 4 ++++ lib/pleroma/web/activity_pub/transmogrifier.ex | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 00cac153d..c7b7b4f0a 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -252,6 +252,10 @@ def following?(%User{} = follower, %User{} = followed) do Enum.member?(follower.following, followed.follower_address) end + def locked?(%User{} = user) do + user.info["locked"] || false + end + def get_by_ap_id(ap_id) do Repo.get_by(User, ap_id: ap_id) end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 75ba36729..7b0d124b2 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -137,9 +137,11 @@ def handle_incoming( with %User{local: true} = followed <- User.get_cached_by_ap_id(followed), %User{} = follower <- User.get_or_fetch_by_ap_id(follower), {:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do - ActivityPub.accept(%{to: [follower.ap_id], actor: followed.ap_id, object: data, local: true}) + if not User.locked?(followed) do + ActivityPub.accept(%{to: [follower.ap_id], actor: followed.ap_id, object: data, local: true}) + User.follow(follower, followed) + end - User.follow(follower, followed) {:ok, activity} else _e -> :error From 6041380774605dd17d7effd3d127dd756c087413 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 26 May 2018 15:03:32 +0000 Subject: [PATCH 03/24] activitypub transmogrifier: learn locked state in Update messages --- 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 7b0d124b2..ab744f6a2 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -254,7 +254,7 @@ def handle_incoming( {:ok, new_user_data} = ActivityPub.user_data_from_user_object(object) banner = new_user_data[:info]["banner"] - locked = new_user_data[:info]["locked"] + locked = new_user_data[:info]["locked"] || false update_data = new_user_data From 9c889334220487c4e370333a13908639b984bc19 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 26 May 2018 16:03:32 +0000 Subject: [PATCH 04/24] implement tracking of follow requests --- lib/pleroma/user.ex | 30 +++++++++++++++++++ lib/pleroma/web/activity_pub/utils.ex | 3 +- .../mastodon_api/mastodon_api_controller.ex | 6 ++++ lib/pleroma/web/router.ex | 4 ++- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index c7b7b4f0a..35f3371ba 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -353,6 +353,36 @@ def get_friends(user) do {:ok, Repo.all(q)} end + def get_follow_requests_query(%User{} = user) do + from( + a in Activity, + where: fragment( + "? ->> 'type' = 'Follow'", + a.data + ), + where: fragment( + "? ->> 'state' = 'pending'", + a.data + ), + where: fragment( + "? @> ?", + a.data, + ^%{"object" => user.ap_id} + ) + ) + end + + def get_follow_requests(%User{} = user) do + q = get_follow_requests_query(user) + reqs = Repo.all(q) + + users = + Enum.map(reqs, fn (req) -> req.actor end) + |> Enum.map(fn (ap_id) -> get_by_ap_id(ap_id) end) + + {:ok, users} + 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) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 56b80a8db..3229949c0 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -219,7 +219,7 @@ def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do @doc """ Makes a follow activity data for the given follower and followed """ - def make_follow_data(%User{ap_id: follower_id}, %User{ap_id: followed_id}, activity_id) do + def make_follow_data(%User{ap_id: follower_id}, %User{ap_id: followed_id} = followed, activity_id) do data = %{ "type" => "Follow", "actor" => follower_id, @@ -229,6 +229,7 @@ def make_follow_data(%User{ap_id: follower_id}, %User{ap_id: followed_id}, activ } if activity_id, do: Map.put(data, "id", activity_id), else: data + if User.locked?(followed), do: Map.put(data, "state", "pending"), else: data end def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 0f7d4bb6d..e92c6277b 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -476,6 +476,12 @@ def following(conn, %{"id" => id}) do end end + def follow_requests(%{assigns: %{user: followed}} = conn, _params) do + with {:ok, follow_requests} <- User.get_follow_requests(followed) do + render(conn, AccountView, "accounts.json", %{users: follow_requests, as: :user}) + end + end + def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do with %User{} = followed <- Repo.get(User, id), {:ok, follower} <- User.maybe_direct_follow(follower, followed), diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 57b10bff1..e517510b8 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -97,11 +97,13 @@ def user_fetcher(username) do post("/accounts/:id/mute", MastodonAPIController, :relationship_noop) post("/accounts/:id/unmute", MastodonAPIController, :relationship_noop) + get("/follow_requests", MastodonAPIController, :follow_requests) + post("/follows", MastodonAPIController, :follow) get("/blocks", MastodonAPIController, :blocks) - get("/follow_requests", MastodonAPIController, :empty_array) + get("/domain_blocks", MastodonAPIController, :empty_array) get("/mutes", MastodonAPIController, :empty_array) get("/timelines/home", MastodonAPIController, :home_timeline) From 6f89d2d583c76d9a2c9908f560902bc75609c8ab Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 26 May 2018 16:16:20 +0000 Subject: [PATCH 05/24] stash api controller --- .../mastodon_api/mastodon_api_controller.ex | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index e92c6277b..90b0da8da 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do alias Pleroma.Web alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView, ListView} alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.{CommonAPI, OStatus} alias Pleroma.Web.OAuth.{Authorization, Token, App} alias Comeonin.Pbkdf2 @@ -482,6 +483,29 @@ def follow_requests(%{assigns: %{user: followed}} = conn, _params) do end end + def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do + with %User{} = follower <- Repo.get(User, id), + {:ok, follower} <- User.follow(follower, followed), + %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), + {:ok, _activity} <- + ActivityPub.accept(%{ + to: follower.ap_id, + actor: followed.ap_id, + object: follow_activity.data["id"], + type: "Accept" + }) do + render(conn, AccountView, "relationship.json", %{user: followed, target: follower}) + else + {:error, message} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(403, Jason.encode!(%{"error" => message})) + end + end + + # def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do + # end + def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do with %User{} = followed <- Repo.get(User, id), {:ok, follower} <- User.maybe_direct_follow(follower, followed), From 760eb72a382b36d37e8fed3a9c0e48360ec65f8d Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 26 May 2018 18:03:23 +0000 Subject: [PATCH 06/24] add a bunch of stuff --- .../web/activity_pub/transmogrifier.ex | 21 ++++++++++++++++ lib/pleroma/web/activity_pub/utils.ex | 20 ++++++++++++++-- .../mastodon_api/mastodon_api_controller.ex | 24 ++++++++++++++++--- lib/pleroma/web/router.ex | 2 ++ 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index ab744f6a2..0ebb49dc0 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -434,6 +434,27 @@ def prepare_outgoing(%{"type" => "Create", "object" => %{"type" => "Note"} = obj {:ok, data} end + # Mastodon Accept/Reject requires a non-normalized object containing the actor URIs, + # because of course it does. + def prepare_outgoing(%{"type" => "Accept"} = data) do + with follow_activity <- Activity.get_by_ap_id(data["object"]) do + object = %{ + "actor" => follow_activity.actor, + "object" => follow_activity.data["object"], + "id" => follow_activity.data["id"], + "type" => "Follow" + } + + data = + data + |> Map.put("object", object) + + IO.inspect(data) + + {:ok, data} + end + end + def prepare_outgoing(%{"type" => _type} = data) do data = data diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 3229949c0..6ce954cd0 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do alias Pleroma.Web.Endpoint alias Ecto.{Changeset, UUID} import Ecto.Query + require Logger # Some implementations send the actor URI as the actor field, others send the entire actor object, # so figure out what the actor's URI is based on what we have. @@ -216,6 +217,19 @@ def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do #### Follow-related helpers + @doc """ + Updates a follow activity's state (for locked accounts). + """ + def update_follow_state(%Activity{} = activity, state) do + with new_data <- + activity.data + |> Map.put("state", state), + changeset <- Changeset.change(activity, data: new_data), + {:ok, activity} <- Repo.update(changeset) do + {:ok, activity} + end + end + @doc """ Makes a follow activity data for the given follower and followed """ @@ -228,8 +242,10 @@ def make_follow_data(%User{ap_id: follower_id}, %User{ap_id: followed_id} = foll "object" => followed_id } - if activity_id, do: Map.put(data, "id", activity_id), else: data - if User.locked?(followed), do: Map.put(data, "state", "pending"), else: data + data = if activity_id, do: Map.put(data, "id", activity_id), else: data + data = if User.locked?(followed), do: Map.put(data, "state", "pending"), else: data + + data end def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 90b0da8da..cae81c43d 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -487,9 +487,10 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id} with %User{} = follower <- Repo.get(User, id), {:ok, follower} <- User.follow(follower, followed), %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), + {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"), {:ok, _activity} <- ActivityPub.accept(%{ - to: follower.ap_id, + to: [follower.ap_id], actor: followed.ap_id, object: follow_activity.data["id"], type: "Accept" @@ -503,8 +504,25 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id} end end - # def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do - # end + def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do + with %User{} = follower <- Repo.get(User, id), + %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), + {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"), + {:ok, _activity} <- + ActivityPub.reject(%{ + to: [follower.ap_id], + actor: followed.ap_id, + object: follow_activity.data["id"], + type: "Reject" + }) do + render(conn, AccountView, "relationship.json", %{user: followed, target: follower}) + else + {:error, message} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(403, Jason.encode!(%{"error" => message})) + end + end def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do with %User{} = followed <- Repo.get(User, id), diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index e517510b8..b37c8168f 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -98,6 +98,8 @@ def user_fetcher(username) do post("/accounts/:id/unmute", MastodonAPIController, :relationship_noop) get("/follow_requests", MastodonAPIController, :follow_requests) + post("/follow_requests/:id/authorize", MastodonAPIController, :authorize_follow_request) + post("/follow_requests/:id/reject", MastodonAPIController, :reject_follow_request) post("/follows", MastodonAPIController, :follow) From 876ad6aa380dcc7ef4888fe31f3b7da567d6f490 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 27 May 2018 09:09:35 +0000 Subject: [PATCH 07/24] activitypub transmogrifier: send @context on accept activities --- lib/pleroma/web/activity_pub/transmogrifier.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 0ebb49dc0..5f5ed7b8e 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -448,6 +448,7 @@ def prepare_outgoing(%{"type" => "Accept"} = data) do data = data |> Map.put("object", object) + |> Map.put("@context", "https://www.w3.org/ns/activitystreams") IO.inspect(data) From f328de8eb77ced729a46e12cbcf898bcfaec78c1 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 27 May 2018 09:10:46 +0000 Subject: [PATCH 08/24] activitypub transmogrifier: send Rejects in the format Mastodon wants --- .../web/activity_pub/transmogrifier.ex | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 5f5ed7b8e..170bfbc03 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -456,6 +456,26 @@ def prepare_outgoing(%{"type" => "Accept"} = data) do end end + def prepare_outgoing(%{"type" => "Reject"} = data) do + with follow_activity <- Activity.get_by_ap_id(data["object"]) do + object = %{ + "actor" => follow_activity.actor, + "object" => follow_activity.data["object"], + "id" => follow_activity.data["id"], + "type" => "Follow" + } + + data = + data + |> Map.put("object", object) + |> Map.put("@context", "https://www.w3.org/ns/activitystreams") + + IO.inspect(data) + + {:ok, data} + end + end + def prepare_outgoing(%{"type" => _type} = data) do data = data From ad7188fe920c5eaa21c38b5f7781a7ba22173b91 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 27 May 2018 09:45:12 +0000 Subject: [PATCH 09/24] user: use Enum.uniq on the follow request query --- lib/pleroma/user.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 35f3371ba..9c0cc7455 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -378,6 +378,7 @@ def get_follow_requests(%User{} = user) do users = Enum.map(reqs, fn (req) -> req.actor end) + |> Enum.uniq |> Enum.map(fn (ap_id) -> get_by_ap_id(ap_id) end) {:ok, users} From a2c4a5a75bc22653553fdf2f3ec25e2c9dd7c66a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 27 May 2018 10:03:53 +0000 Subject: [PATCH 10/24] mastodon api: allow setting an account locked or not --- .../web/mastodon_api/mastodon_api_controller.ex | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index cae81c43d..caff4ad86 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -72,6 +72,20 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do 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 if original_user != user do From 76f80ba8c23798d69ecc6b89d6fd42a1d37adeed Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 27 May 2018 13:51:13 +0000 Subject: [PATCH 11/24] activitypub: when unfollowing, update the follow activity's disposition to 'cancelled' so it cannot be reused --- lib/pleroma/web/activity_pub/activity_pub.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 43e96fe37..3c2875548 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -214,6 +214,7 @@ def follow(follower, followed, activity_id \\ nil, local \\ true) do def unfollow(follower, followed, activity_id \\ nil, local \\ true) do with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed), + {:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"), unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id), {:ok, activity} <- insert(unfollow_data, local), :ok <- maybe_federate(activity) do From 1452b2823fbd858f2b818c35ca1faedb0d222690 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 28 May 2018 16:42:18 +0000 Subject: [PATCH 12/24] user: add a workaround for situations where Pleroma may believe a followee is followed this was caused by lack of Undo follows in the early days, and can likely be eventually removed --- lib/pleroma/user.ex | 8 ++++++++ lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 9c0cc7455..1dcb68470 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -197,6 +197,14 @@ def maybe_direct_follow(%User{} = follower, %User{info: info} = followed) do end end + def maybe_follow(%User{} = follower, %User{info: info} = followed) do + if not following?(follower, followed) do + follow(follower, followed) + else + {:ok, follower} + end + end + def follow(%User{} = follower, %User{info: info} = followed) do ap_followers = followed.follower_address diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index caff4ad86..922b83ed0 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -499,7 +499,7 @@ def follow_requests(%{assigns: %{user: followed}} = conn, _params) do def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do with %User{} = follower <- Repo.get(User, id), - {:ok, follower} <- User.follow(follower, followed), + {:ok, follower} <- User.maybe_follow(follower, followed), %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"), {:ok, _activity} <- From 4084889a2d2a00828b2909ee5356f86b42d747e8 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 28 May 2018 17:42:58 +0000 Subject: [PATCH 13/24] activitypub transmogrifier: remove debug code --- lib/pleroma/web/activity_pub/transmogrifier.ex | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 170bfbc03..dffe2f159 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -450,8 +450,6 @@ def prepare_outgoing(%{"type" => "Accept"} = data) do |> Map.put("object", object) |> Map.put("@context", "https://www.w3.org/ns/activitystreams") - IO.inspect(data) - {:ok, data} end end @@ -470,8 +468,6 @@ def prepare_outgoing(%{"type" => "Reject"} = data) do |> Map.put("object", object) |> Map.put("@context", "https://www.w3.org/ns/activitystreams") - IO.inspect(data) - {:ok, data} end end From c99b9b9d926b30e417c2a44fa3f0f64029f76b2d Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 28 May 2018 17:45:23 +0000 Subject: [PATCH 14/24] testsuite: add mastodon api tests --- .../mastodon_api_controller_test.exs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 566f5acfc..e45b5c9c2 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -4,6 +4,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.{Repo, User, Activity, Notification} alias Pleroma.Web.{OStatus, CommonAPI} + alias Pleroma.Web.ActivityPub.ActivityPub import Pleroma.Factory import ExUnit.CaptureLog @@ -644,6 +645,63 @@ test "returns the relationships for the current user", %{conn: conn} do end end + describe "locked accounts" do + test "/api/v1/follow_requests works" do + user = insert(:user, %{info: %{"locked" => true}}) + other_user = insert(:user) + + {:ok, activity} = ActivityPub.follow(other_user, user) + + conn = + build_conn() + |> assign(:user, user) + |> get("/api/v1/follow_requests") + + assert [relationship] = json_response(conn, 200) + assert to_string(other_user.id) == relationship["id"] + end + + test "/api/v1/follow_requests/:id/authorize works" do + user = insert(:user, %{info: %{"locked" => true}}) + other_user = insert(:user) + + {:ok, activity} = ActivityPub.follow(other_user, user) + + conn = + build_conn() + |> assign(:user, user) + |> post("/api/v1/follow_requests/#{other_user.id}/authorize") + + assert relationship = json_response(conn, 200) + assert to_string(other_user.id) == relationship["id"] + + user = Repo.get(User, user.id) + other_user = Repo.get(User, other_user.id) + + assert User.following?(other_user, user) == true + end + + test "/api/v1/follow_requests/:id/reject works" do + user = insert(:user, %{info: %{"locked" => true}}) + other_user = insert(:user) + + {:ok, activity} = ActivityPub.follow(other_user, user) + + conn = + build_conn() + |> assign(:user, user) + |> post("/api/v1/follow_requests/#{other_user.id}/reject") + + assert relationship = json_response(conn, 200) + assert to_string(other_user.id) == relationship["id"] + + user = Repo.get(User, user.id) + other_user = Repo.get(User, other_user.id) + + assert User.following?(other_user, user) == false + end + end + test "account fetching", %{conn: conn} do user = insert(:user) From a0c5b42e293959c7bc448f171fc38c2c26f91d18 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 28 May 2018 17:51:50 +0000 Subject: [PATCH 15/24] tests: assert the state prior to mutating it as well as afterward --- test/web/mastodon_api/mastodon_api_controller_test.exs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index e45b5c9c2..d1812457d 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -652,6 +652,11 @@ test "/api/v1/follow_requests works" do {:ok, activity} = ActivityPub.follow(other_user, user) + user = Repo.get(User, user.id) + other_user = Repo.get(User, other_user.id) + + assert User.following?(other_user, user) == false + conn = build_conn() |> assign(:user, user) @@ -667,6 +672,11 @@ test "/api/v1/follow_requests/:id/authorize works" do {:ok, activity} = ActivityPub.follow(other_user, user) + user = Repo.get(User, user.id) + other_user = Repo.get(User, other_user.id) + + assert User.following?(other_user, user) == false + conn = build_conn() |> assign(:user, user) From 993312cdb3ec219f1cf29e14be97f2b98bc90a9c Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 28 May 2018 18:19:20 +0000 Subject: [PATCH 16/24] twitterapi: add profile setting for locked/unlocked accounts --- .../web/twitter_api/twitter_api_controller.ex | 14 ++++++++ .../twitter_api_controller_test.exs | 32 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index d53dd0c44..b078c447e 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -357,6 +357,20 @@ def update_profile(%{assigns: %{user: user}} = conn, params) do 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 + with changeset <- User.update_changeset(user, params), {:ok, user} <- User.update_and_set_cache(changeset) do CommonAPI.update(user) diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index 68f4331df..6a29d583c 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -762,6 +762,38 @@ test "it updates a user's profile", %{conn: conn} do assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) end + + test "it locks an account", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> post("/api/account/update_profile.json", %{ + "locked" => "true" + }) + + user = Repo.get!(User, user.id) + assert user.info["locked"] == true + + assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) + end + + test "it unlocks an account", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> post("/api/account/update_profile.json", %{ + "locked" => "false" + }) + + user = Repo.get!(User, user.id) + assert user.info["locked"] == false + + assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) + end end defp valid_user(_context) do From 5eed1ea18145b16999b29f0a4c2313784c8cff0e Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 28 May 2018 18:31:48 +0000 Subject: [PATCH 17/24] run mix format --- lib/pleroma/user.ex | 35 ++++++++++--------- .../web/activity_pub/transmogrifier.ex | 8 ++++- lib/pleroma/web/activity_pub/utils.ex | 6 +++- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1dcb68470..b27397e13 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -364,19 +364,22 @@ def get_friends(user) do def get_follow_requests_query(%User{} = user) do from( a in Activity, - where: fragment( - "? ->> 'type' = 'Follow'", - a.data - ), - where: fragment( - "? ->> 'state' = 'pending'", - a.data - ), - where: fragment( - "? @> ?", - a.data, - ^%{"object" => user.ap_id} - ) + where: + fragment( + "? ->> 'type' = 'Follow'", + a.data + ), + where: + fragment( + "? ->> 'state' = 'pending'", + a.data + ), + where: + fragment( + "? @> ?", + a.data, + ^%{"object" => user.ap_id} + ) ) end @@ -385,9 +388,9 @@ def get_follow_requests(%User{} = user) do reqs = Repo.all(q) users = - Enum.map(reqs, fn (req) -> req.actor end) - |> Enum.uniq - |> Enum.map(fn (ap_id) -> get_by_ap_id(ap_id) end) + Enum.map(reqs, fn req -> req.actor end) + |> Enum.uniq() + |> Enum.map(fn ap_id -> get_by_ap_id(ap_id) end) {:ok, users} end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index dffe2f159..08173f78d 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -138,7 +138,13 @@ def handle_incoming( %User{} = follower <- User.get_or_fetch_by_ap_id(follower), {:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do if not User.locked?(followed) do - ActivityPub.accept(%{to: [follower.ap_id], actor: followed.ap_id, object: data, local: true}) + ActivityPub.accept(%{ + to: [follower.ap_id], + actor: followed.ap_id, + object: data, + local: true + }) + User.follow(follower, followed) end diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 6ce954cd0..64329b710 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -233,7 +233,11 @@ def update_follow_state(%Activity{} = activity, state) do @doc """ Makes a follow activity data for the given follower and followed """ - def make_follow_data(%User{ap_id: follower_id}, %User{ap_id: followed_id} = followed, activity_id) do + def make_follow_data( + %User{ap_id: follower_id}, + %User{ap_id: followed_id} = followed, + activity_id + ) do data = %{ "type" => "Follow", "actor" => follower_id, From d96377f3590c08a2c38941299aedb977b1b5a8e5 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 29 May 2018 10:18:23 +0000 Subject: [PATCH 18/24] activitypub transmogrifier: accept/reject outgoing: we might send the actual object instead of the URI in some cases, handle it --- lib/pleroma/web/activity_pub/transmogrifier.ex | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 08173f78d..e7a3420d2 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -443,7 +443,14 @@ def prepare_outgoing(%{"type" => "Create", "object" => %{"type" => "Note"} = obj # Mastodon Accept/Reject requires a non-normalized object containing the actor URIs, # because of course it does. def prepare_outgoing(%{"type" => "Accept"} = data) do - with follow_activity <- Activity.get_by_ap_id(data["object"]) do + follow_activity_id = + if is_binary(data["object"]) do + data["object"] + else + data["object"]["id"] + end + + with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do object = %{ "actor" => follow_activity.actor, "object" => follow_activity.data["object"], @@ -461,7 +468,14 @@ def prepare_outgoing(%{"type" => "Accept"} = data) do end def prepare_outgoing(%{"type" => "Reject"} = data) do - with follow_activity <- Activity.get_by_ap_id(data["object"]) do + follow_activity_id = + if is_binary(data["object"]) do + data["object"] + else + data["object"]["id"] + end + + with follow_activity <- Activity.get_by_ap_id(follow_activity_id) do object = %{ "actor" => follow_activity.actor, "object" => follow_activity.data["object"], From ba8dab75426fbd881c7b8fd814934d46fc48e9ba Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 29 May 2018 14:13:34 +0000 Subject: [PATCH 19/24] twitterapi: user view: return if an account is locked or not --- lib/pleroma/web/twitter_api/views/user_view.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index 31527caae..711008973 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -51,7 +51,8 @@ def render("user.json", %{user: user = %User{}} = assigns) do "statusnet_profile_url" => user.ap_id, "cover_photo" => User.banner_url(user) |> MediaProxy.url(), "background_image" => image_url(user.info["background"]) |> MediaProxy.url(), - "is_local" => user.local + "is_local" => user.local, + "locked" => !!user.info["locked"] } if assigns[:token] do From e08cf21e5b45f263d7f75641f3a91a5329488f82 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 29 May 2018 15:30:06 +0000 Subject: [PATCH 20/24] twitter api: add friend requests list api --- lib/pleroma/web/router.ex | 2 ++ lib/pleroma/web/twitter_api/twitter_api_controller.ex | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index b37c8168f..ea134bbff 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -247,6 +247,8 @@ def user_fetcher(username) do post("/statuses/retweet/:id", TwitterAPI.Controller, :retweet) post("/statuses/destroy/:id", TwitterAPI.Controller, :delete_post) + get("/pleroma/friend_requests", TwitterAPI.Controller, :friend_requests) + post("/friendships/create", TwitterAPI.Controller, :follow) post("/friendships/destroy", TwitterAPI.Controller, :unfollow) post("/blocks/create", TwitterAPI.Controller, :block) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index b078c447e..123d20177 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -331,6 +331,15 @@ def friends(conn, params) do end end + def friend_requests(conn, params) do + with {:ok, user} <- TwitterAPI.get_user(conn.assigns.user, params), + {:ok, friend_requests} <- User.get_follow_requests(user) do + render(conn, UserView, "index.json", %{users: friend_requests, for: user}) + else + _e -> bad_request_reply(conn, "Can't get friend requests") + end + end + def friends_ids(%{assigns: %{user: user}} = conn, _params) do with {:ok, friends} <- User.get_friends(user) do ids = From d116af3bee6dcad1cb5c33030bdff72335791065 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Wed, 6 Jun 2018 23:46:55 +0000 Subject: [PATCH 21/24] tests: add tests for /api/pleroma/friend_requests --- .../twitter_api_controller_test.exs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index 6a29d583c..ac8ccfbc3 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -958,4 +958,26 @@ test "with credentials and valid password", %{conn: conn, user: current_user} do :timer.sleep(1000) end end + + describe "GET /api/pleroma/friend_requests" do + test "it lists friend requests" do + user = insert(:user, %{info: %{"locked" => true}}) + other_user = insert(:user) + + {:ok, activity} = ActivityPub.follow(other_user, user) + + user = Repo.get(User, user.id) + other_user = Repo.get(User, other_user.id) + + assert User.following?(other_user, user) == false + + conn = + build_conn() + |> assign(:user, user) + |> get("/api/pleroma/friend_requests") + + assert [relationship] = json_response(conn, 200) + assert other_user.id == relationship["id"] + end + end end From f8e0942745636f0f51e5ff57d1b40f79ee82f87b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 7 Jun 2018 00:04:03 +0000 Subject: [PATCH 22/24] twitter api: add approve/deny endpoints --- lib/pleroma/web/router.ex | 2 + .../web/twitter_api/twitter_api_controller.ex | 44 +++++++++++++++++- .../twitter_api_controller_test.exs | 46 +++++++++++++++++++ 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index ea134bbff..6f8b427b5 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -248,6 +248,8 @@ def user_fetcher(username) do post("/statuses/destroy/:id", TwitterAPI.Controller, :delete_post) get("/pleroma/friend_requests", TwitterAPI.Controller, :friend_requests) + post("/pleroma/friendships/approve", TwitterAPI.Controller, :approve_friend_request) + post("/pleroma/friendships/deny", TwitterAPI.Controller, :deny_friend_request) post("/friendships/create", TwitterAPI.Controller, :follow) post("/friendships/destroy", TwitterAPI.Controller, :unfollow) diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 123d20177..b29687df5 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do alias Pleroma.Web.CommonAPI alias Pleroma.{Repo, Activity, User, Notification} alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.Utils alias Ecto.Changeset require Logger @@ -332,14 +333,53 @@ def friends(conn, params) do end def friend_requests(conn, params) do - with {:ok, user} <- TwitterAPI.get_user(conn.assigns.user, params), + with {:ok, user} <- TwitterAPI.get_user(conn.assigns[:user], params), {:ok, friend_requests} <- User.get_follow_requests(user) do - render(conn, UserView, "index.json", %{users: friend_requests, for: user}) + render(conn, UserView, "index.json", %{users: friend_requests, for: conn.assigns[:user]}) else _e -> bad_request_reply(conn, "Can't get friend requests") end end + def approve_friend_request(conn, %{"user_id" => uid} = params) do + with followed <- conn.assigns[:user], + uid when is_number(uid) <- String.to_integer(uid), + %User{} = follower <- Repo.get(User, uid), + {:ok, follower} <- User.maybe_follow(follower, followed), + %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), + {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"), + {:ok, _activity} <- + ActivityPub.accept(%{ + to: [follower.ap_id], + actor: followed.ap_id, + object: follow_activity.data["id"], + type: "Accept" + }) do + render(conn, UserView, "show.json", %{user: follower, for: followed}) + else + e -> bad_request_reply(conn, "Can't approve user: #{inspect(e)}") + end + end + + def deny_friend_request(conn, %{"user_id" => uid} = params) do + with followed <- conn.assigns[:user], + uid when is_number(uid) <- String.to_integer(uid), + %User{} = follower <- Repo.get(User, uid), + %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), + {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"), + {:ok, _activity} <- + ActivityPub.reject(%{ + to: [follower.ap_id], + actor: followed.ap_id, + object: follow_activity.data["id"], + type: "Reject" + }) do + render(conn, UserView, "show.json", %{user: follower, for: followed}) + else + e -> bad_request_reply(conn, "Can't deny user: #{inspect(e)}") + end + end + def friends_ids(%{assigns: %{user: user}} = conn, _params) do with {:ok, friends} <- User.get_friends(user) do ids = diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index ac8ccfbc3..bd11551df 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -980,4 +980,50 @@ test "it lists friend requests" do assert other_user.id == relationship["id"] end end + + describe "POST /api/pleroma/friendships/approve" do + test "it approves a friend request" do + user = insert(:user, %{info: %{"locked" => true}}) + other_user = insert(:user) + + {:ok, activity} = ActivityPub.follow(other_user, user) + + user = Repo.get(User, user.id) + other_user = Repo.get(User, other_user.id) + + assert User.following?(other_user, user) == false + + conn = + build_conn() + |> assign(:user, user) + |> post("/api/pleroma/friendships/approve", %{"user_id" => to_string(other_user.id)}) + + assert relationship = json_response(conn, 200) + assert other_user.id == relationship["id"] + assert relationship["follows_you"] == true + end + end + + describe "POST /api/pleroma/friendships/deny" do + test "it denies a friend request" do + user = insert(:user, %{info: %{"locked" => true}}) + other_user = insert(:user) + + {:ok, activity} = ActivityPub.follow(other_user, user) + + user = Repo.get(User, user.id) + other_user = Repo.get(User, other_user.id) + + assert User.following?(other_user, user) == false + + conn = + build_conn() + |> assign(:user, user) + |> post("/api/pleroma/friendships/deny", %{"user_id" => to_string(other_user.id)}) + + assert relationship = json_response(conn, 200) + assert other_user.id == relationship["id"] + assert relationship["follows_you"] == false + end + end end From c773f42ca4814276b56cba743883b38cec0c9e8c Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 7 Jun 2018 19:43:52 +0000 Subject: [PATCH 23/24] tests: update twitterapi user view tests for new locked variable --- test/web/twitter_api/views/user_view_test.exs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs index 9f8bf4cdc..eea743b32 100644 --- a/test/web/twitter_api/views/user_view_test.exs +++ b/test/web/twitter_api/views/user_view_test.exs @@ -59,7 +59,8 @@ test "A user" do "statusnet_profile_url" => user.ap_id, "cover_photo" => banner, "background_image" => nil, - "is_local" => true + "is_local" => true, + "locked" => false } assert represented == UserView.render("show.json", %{user: user}) @@ -94,7 +95,8 @@ test "A user for a given other follower", %{user: user} do "statusnet_profile_url" => user.ap_id, "cover_photo" => banner, "background_image" => nil, - "is_local" => true + "is_local" => true, + "locked" => false } assert represented == UserView.render("show.json", %{user: user, for: follower}) @@ -130,7 +132,8 @@ test "A user that follows you", %{user: user} do "statusnet_profile_url" => follower.ap_id, "cover_photo" => banner, "background_image" => nil, - "is_local" => true + "is_local" => true, + "locked" => false } assert represented == UserView.render("show.json", %{user: follower, for: user}) @@ -173,7 +176,8 @@ test "A blocked user for the blocker" do "statusnet_profile_url" => user.ap_id, "cover_photo" => banner, "background_image" => nil, - "is_local" => true + "is_local" => true, + "locked" => false } blocker = Repo.get(User, blocker.id) From 98104712379f4d001fc633eed7cfab69224816bc Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 11 Jun 2018 23:40:19 +0000 Subject: [PATCH 24/24] router: remove stub /domain_blocks entry --- lib/pleroma/web/router.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 6f8b427b5..ee6a373d3 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -105,7 +105,6 @@ def user_fetcher(username) do get("/blocks", MastodonAPIController, :blocks) - get("/domain_blocks", MastodonAPIController, :empty_array) get("/mutes", MastodonAPIController, :empty_array) get("/timelines/home", MastodonAPIController, :home_timeline)