From 49f2cd6932f5e71e7ab0fae81580074c1b8e0986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Wed, 16 Mar 2022 14:39:02 +0100 Subject: [PATCH] POST /api/v1/accounts/:id/remove_from_followers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- .../api_spec/operations/account_operation.ex | 16 +++++++++++ .../controllers/account_controller.ex | 18 ++++++++++--- lib/pleroma/web/router.ex | 1 + .../controllers/account_controller_test.exs | 27 +++++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index b1f4932ee..b305dc1ea 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -334,6 +334,22 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do } end + def remove_from_followers_operation do + %Operation{ + tags: ["Account actions"], + summary: "Remove from followers", + operationId: "AccountController.remove_from_followers", + security: [%{"oAuth" => ["follow", "write:follows"]}], + description: "Remove the given account from followers", + parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}], + responses: %{ + 200 => Operation.response("Relationship", "application/json", AccountRelationship), + 400 => Operation.response("Error", "application/json", ApiError), + 404 => Operation.response("Error", "application/json", ApiError) + } + } + end + def note_operation do %Operation{ tags: ["Account actions"], diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index ed7fb802a..6fb80d35c 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -76,15 +76,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do plug( OAuthScopesPlug, - %{scopes: ["follow", "write:follows"]} when action in [:follow_by_uri, :follow, :unfollow] + %{scopes: ["follow", "write:follows"]} + when action in [:follow_by_uri, :follow, :unfollow, :remove_from_followers] ) plug(OAuthScopesPlug, %{scopes: ["follow", "read:mutes"]} when action == :mutes) plug(OAuthScopesPlug, %{scopes: ["follow", "write:mutes"]} when action in [:mute, :unmute]) - @relationship_actions [:follow, :unfollow] - @needs_account ~W(followers following lists follow unfollow mute unmute block unblock note)a + @relationship_actions [:follow, :unfollow, :remove_from_followers] + @needs_account ~W(followers following lists follow unfollow mute unmute block unblock note remove_from_followers)a plug( RateLimiter, @@ -447,6 +448,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do end end + @doc "POST /api/v1/accounts/:id/remove_from_followers" + def remove_from_followers(%{assigns: %{user: %{id: id}, account: %{id: id}}}, _params) do + {:error, "Can not unfollow yourself"} + end + + def remove_from_followers(%{assigns: %{user: follower, account: followed}} = conn, _params) do + with {:ok, follower} <- CommonAPI.unfollow(followed, follower) do + render(conn, "relationship.json", user: follower, target: followed) + end + end + @doc "POST /api/v1/follows" def follow_by_uri(%{body_params: %{uri: uri}} = conn, _) do case User.get_cached_by_nickname(uri) do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 838599c4d..71a9e4d29 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -509,6 +509,7 @@ defmodule Pleroma.Web.Router do post("/accounts/:id/mute", AccountController, :mute) post("/accounts/:id/unmute", AccountController, :unmute) post("/accounts/:id/note", AccountController, :note) + post("/accounts/:id/remove_from_followers", AccountController, :remove_from_followers) get("/conversations", ConversationController, :index) post("/conversations/:id/read", ConversationController, :mark_as_read) diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index dcdff6c09..c0962e699 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -1921,4 +1921,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> get("/api/v1/accounts/relationships?id=#{other_user.id}") |> json_response_and_validate_schema(200) end + + describe "remove from followers" do + setup do: oauth_access(["follow"]) + + test "removing user from followers", %{conn: conn, user: user} do + %{id: other_user_id} = other_user = insert(:user) + + CommonAPI.follow(other_user, user) + + assert %{"id" => _id, "followed_by" => false} = + conn + |> post("/api/v1/accounts/#{other_user_id}/remove_from_followers") + |> json_response_and_validate_schema(200) + end + + test "removing user from followers errors", %{user: user, conn: conn} do + # self remove + conn_res = post(conn, "/api/v1/accounts/#{user.id}/remove_from_followers") + + assert %{"error" => "Can not unfollow yourself"} = + json_response_and_validate_schema(conn_res, 400) + + # remove non existing user + conn_res = post(conn, "/api/v1/accounts/doesntexist/remove_from_followers") + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) + end + end end