excluded invisible actors from gets /api/v1/accounts/:id
authorMaksim Pechnikov <parallel588@gmail.com>
Mon, 4 Nov 2019 17:44:24 +0000 (20:44 +0300)
committerMaksim Pechnikov <parallel588@gmail.com>
Mon, 4 Nov 2019 17:44:24 +0000 (20:44 +0300)
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/relay.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
priv/repo/migrations/20191104133100_set_visible_service_actors.exs [new file with mode: 0644]
test/user_test.exs
test/web/mastodon_api/controllers/account_controller_test.exs

index f8c2db1e1ebc3b1128c288db28f2229970d1c779..abd1dd9369d5df794046d43a20be63134779bc57 100644 (file)
@@ -131,6 +131,8 @@ defmodule Pleroma.User do
 
   def visible_for?(user, for_user \\ nil)
 
+  def visible_for?(%User{invisible: true}, _), do: false
+
   def visible_for?(%User{id: user_id}, %User{id: for_id}) when user_id == for_id, do: true
 
   def visible_for?(%User{} = user, for_user) do
@@ -1314,22 +1316,23 @@ defmodule Pleroma.User do
     end
   end
 
-  @doc "Creates an internal service actor by URI if missing.  Optionally takes nickname for addressing."
+  @doc """
+  Creates an internal service actor by URI if missing.
+  Optionally takes nickname for addressing.
+  """
   def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do
-    with %User{} = user <- get_cached_by_ap_id(uri) do
-      user
-    else
-      _ ->
-        {:ok, user} =
-          %User{}
-          |> cast(%{}, [:ap_id, :nickname, :local])
-          |> put_change(:ap_id, uri)
-          |> put_change(:nickname, nickname)
-          |> put_change(:local, true)
-          |> put_change(:follower_address, uri <> "/followers")
-          |> Repo.insert()
+    with user when is_nil(user) <- get_cached_by_ap_id(uri) do
+      {:ok, user} =
+        %User{
+          invisible: true,
+          local: true,
+          ap_id: uri,
+          nickname: nickname,
+          follower_address: uri <> "/followers"
+        }
+        |> Repo.insert()
 
-        user
+      user
     end
   end
 
index fc2619680f8e00d96606e7918b1291d65519dbe5..99a804568ccf0830529d55d1c17e916fce146c5f 100644 (file)
@@ -14,7 +14,6 @@ defmodule Pleroma.Web.ActivityPub.Relay do
       relay_ap_id()
       |> User.get_or_create_service_actor_by_ap_id()
 
-    {:ok, actor} = User.set_invisible(actor, true)
     actor
   end
 
index 73fad519ecbe1259f3ab0782beaddbf818943bcc..8f5b91f04326047cdd80cd350513fb57c37a3e0e 100644 (file)
@@ -238,7 +238,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
   @doc "GET /api/v1/accounts/:id"
   def show(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
     with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user),
-         true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do
+         true <- User.visible_for?(user, for_user) do
       render(conn, "show.json", user: user, for: for_user)
     else
       _e -> render_error(conn, :not_found, "Can't find user")
diff --git a/priv/repo/migrations/20191104133100_set_visible_service_actors.exs b/priv/repo/migrations/20191104133100_set_visible_service_actors.exs
new file mode 100644 (file)
index 0000000..6290709
--- /dev/null
@@ -0,0 +1,22 @@
+defmodule Pleroma.Repo.Migrations.SetVisibleServiceActors do
+  use Ecto.Migration
+  import Ecto.Query
+  alias Pleroma.Repo
+
+  def up do
+    user_nicknames = ["relay", "internal.fetch"]
+
+    from(
+      u in "users",
+      where: u.nickname in ^user_nicknames,
+      update: [
+        set: [invisible: true]
+      ]
+    )
+    |> Repo.update_all([])
+  end
+
+  def down do
+    :ok
+  end
+end
index 6b1b24ce5fd2ef5693937bd867b067fe420d5bd3..485106b753fb9f3af4a917adb1da304c61a06ab9 100644 (file)
@@ -25,6 +25,25 @@ defmodule Pleroma.UserTest do
 
   clear_config([:instance, :account_activation_required])
 
+  describe "service actors" do
+    test "returns invisible actor" do
+      uri = "#{Pleroma.Web.Endpoint.url()}/internal/fetch-test"
+      followers_uri = "#{uri}/followers"
+      user = User.get_or_create_service_actor_by_ap_id(uri, "internal.fetch-test")
+
+      assert %User{
+               nickname: "internal.fetch-test",
+               invisible: true,
+               local: true,
+               ap_id: ^uri,
+               follower_address: ^followers_uri
+             } = user
+
+      user2 = User.get_or_create_service_actor_by_ap_id(uri, "internal.fetch-test")
+      assert user.id == user2.id
+    end
+  end
+
   describe "when tags are nil" do
     test "tagging a user" do
       user = insert(:user, %{tags: nil})
index 8fc2d93005f5cda6ec224ff92eaf078771b19581..585cb8a9e95d54b00572a949530d61e8416b9b25 100644 (file)
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
   alias Pleroma.Repo
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.ActivityPub.InternalFetchActor
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.OAuth.Token
 
@@ -118,6 +119,28 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
       refute acc_one == acc_two
       assert acc_two == acc_three
     end
+
+    test "returns 404 when user is invisible", %{conn: conn} do
+      user = insert(:user, %{invisible: true})
+
+      resp =
+        conn
+        |> get("/api/v1/accounts/#{user.nickname}")
+        |> json_response(404)
+
+      assert %{"error" => "Can't find user"} = resp
+    end
+
+    test "returns 404 for internal.fetch actor", %{conn: conn} do
+      %User{nickname: "internal.fetch"} = InternalFetchActor.get_actor()
+
+      resp =
+        conn
+        |> get("/api/v1/accounts/internal.fetch")
+        |> json_response(404)
+
+      assert %{"error" => "Can't find user"} = resp
+    end
   end
 
   describe "user timelines" do