From 78e3bcb2f821fc390bfcd98f07489fcfbf655c98 Mon Sep 17 00:00:00 2001
From: Thomas Citharel <tcit@tcit.fr>
Date: Mon, 2 Nov 2020 18:11:27 +0100
Subject: [PATCH] Add proper error message when accessing followers/followings
 w/ auth

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
---
 lib/graphql/resolvers/admin.ex        |  16 +++
 test/graphql/resolvers/admin_test.exs | 176 +++++++++++++++++++++-----
 2 files changed, 159 insertions(+), 33 deletions(-)

diff --git a/lib/graphql/resolvers/admin.ex b/lib/graphql/resolvers/admin.ex
index 55eedeaf0..6aa412882 100644
--- a/lib/graphql/resolvers/admin.ex
+++ b/lib/graphql/resolvers/admin.ex
@@ -274,6 +274,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
     end
   end
 
+  def list_relay_followers(_parent, _args, %{context: %{current_user: %User{}}}) do
+    {:error, :unauthorized}
+  end
+
+  def list_relay_followers(_parent, _args, _resolution) do
+    {:error, :unauthenticated}
+  end
+
   def list_relay_followings(
         _parent,
         %{page: page, limit: limit},
@@ -288,6 +296,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
     end
   end
 
+  def list_relay_followings(_parent, _args, %{context: %{current_user: %User{}}}) do
+    {:error, :unauthorized}
+  end
+
+  def list_relay_followings(_parent, _args, _resolution) do
+    {:error, :unauthenticated}
+  end
+
   def create_relay(_parent, %{address: address}, %{context: %{current_user: %User{role: role}}})
       when is_admin(role) do
     case Relay.follow(address) do
diff --git a/test/graphql/resolvers/admin_test.exs b/test/graphql/resolvers/admin_test.exs
index 8b94e16d0..d079568e7 100644
--- a/test/graphql/resolvers/admin_test.exs
+++ b/test/graphql/resolvers/admin_test.exs
@@ -124,6 +124,90 @@ defmodule Mobilizon.GraphQL.Resolvers.AdminTest do
   end
 
   describe "Resolver: Get the list of relay followers" do
+    @relay_followers_query """
+    {
+      relayFollowers {
+        elements {
+          actor {
+            preferredUsername,
+            domain,
+          },
+          approved
+        },
+        total
+      }
+    }
+    """
+
+    @relay_followings_query """
+    {
+        relayFollowings {
+          elements {
+            targetActor {
+              preferredUsername,
+              domain,
+            },
+            approved
+          },
+          total
+        }
+      }
+    """
+
+    test "test list_relay_followers/3 returns nothing when not logged-in", %{conn: conn} do
+      follower_actor =
+        insert(:actor,
+          domain: "localhost",
+          user: nil,
+          url: "http://localhost:8080/actor",
+          preferred_username: "instance_actor",
+          name: "I am an instance actor"
+        )
+
+      %Actor{} = relay_actor = Relay.get_actor()
+      insert(:follower, actor: follower_actor, target_actor: relay_actor)
+
+      res =
+        conn
+        |> AbsintheHelpers.graphql_query(query: @relay_followers_query)
+
+      assert hd(res["errors"])["message"] == "You need to be logged in"
+      assert hd(res["errors"])["status_code"] == 401
+    end
+
+    test "test list_relay_followers/3 returns nothing when not an admin", %{conn: conn} do
+      %User{} = user_moderator = insert(:user, role: :moderator)
+      %User{} = user = insert(:user)
+
+      follower_actor =
+        insert(:actor,
+          domain: "localhost",
+          user: nil,
+          url: "http://localhost:8080/actor",
+          preferred_username: "instance_actor",
+          name: "I am an instance actor"
+        )
+
+      %Actor{} = relay_actor = Relay.get_actor()
+      insert(:follower, actor: follower_actor, target_actor: relay_actor)
+
+      res =
+        conn
+        |> auth_conn(user_moderator)
+        |> AbsintheHelpers.graphql_query(query: @relay_followers_query)
+
+      assert hd(res["errors"])["message"] == "You don't have permission to do this"
+      assert hd(res["errors"])["status_code"] == 403
+
+      res =
+        conn
+        |> auth_conn(user)
+        |> AbsintheHelpers.graphql_query(query: @relay_followers_query)
+
+      assert hd(res["errors"])["message"] == "You don't have permission to do this"
+      assert hd(res["errors"])["status_code"] == 403
+    end
+
     test "test list_relay_followers/3 returns relay followers", %{conn: conn} do
       %User{} = user_admin = insert(:user, role: :administrator)
 
@@ -139,25 +223,10 @@ defmodule Mobilizon.GraphQL.Resolvers.AdminTest do
       %Actor{} = relay_actor = Relay.get_actor()
       insert(:follower, actor: follower_actor, target_actor: relay_actor)
 
-      query = """
-      {
-        relayFollowers {
-          elements {
-            actor {
-              preferredUsername,
-              domain,
-            },
-            approved
-          },
-          total
-        }
-      }
-      """
-
       res =
         conn
         |> auth_conn(user_admin)
-        |> AbsintheHelpers.graphql_query(query: query)
+        |> AbsintheHelpers.graphql_query(query: @relay_followers_query)
 
       assert is_nil(res["errors"])
 
@@ -167,7 +236,63 @@ defmodule Mobilizon.GraphQL.Resolvers.AdminTest do
              }
     end
 
-    test "test list_relay_followers/3 returns relay followings", %{conn: conn} do
+    test "test list_relay_followings/3 returns nothing when not logged-in", %{conn: conn} do
+      %Actor{} =
+        following_actor =
+        insert(:actor,
+          domain: "localhost",
+          user: nil,
+          url: "http://localhost:8080/actor",
+          preferred_username: "instance_actor",
+          name: "I am an instance actor"
+        )
+
+      %Actor{} = relay_actor = Relay.get_actor()
+      insert(:follower, actor: relay_actor, target_actor: following_actor)
+
+      res =
+        conn
+        |> AbsintheHelpers.graphql_query(query: @relay_followings_query)
+
+      assert hd(res["errors"])["message"] == "You need to be logged in"
+      assert hd(res["errors"])["status_code"] == 401
+    end
+
+    test "test list_relay_followings/3 returns nothing when not an admin", %{conn: conn} do
+      %User{} = user_moderator = insert(:user, role: :moderator)
+      %User{} = user = insert(:user)
+
+      %Actor{} =
+        following_actor =
+        insert(:actor,
+          domain: "localhost",
+          user: nil,
+          url: "http://localhost:8080/actor",
+          preferred_username: "instance_actor",
+          name: "I am an instance actor"
+        )
+
+      %Actor{} = relay_actor = Relay.get_actor()
+      insert(:follower, actor: relay_actor, target_actor: following_actor)
+
+      res =
+        conn
+        |> auth_conn(user_moderator)
+        |> AbsintheHelpers.graphql_query(query: @relay_followings_query)
+
+      assert hd(res["errors"])["message"] == "You don't have permission to do this"
+      assert hd(res["errors"])["status_code"] == 403
+
+      res =
+        conn
+        |> auth_conn(user)
+        |> AbsintheHelpers.graphql_query(query: @relay_followings_query)
+
+      assert hd(res["errors"])["message"] == "You don't have permission to do this"
+      assert hd(res["errors"])["status_code"] == 403
+    end
+
+    test "test list_relay_followings/3 returns relay followings", %{conn: conn} do
       %User{} = user_admin = insert(:user, role: :administrator)
 
       %Actor{
@@ -186,25 +311,10 @@ defmodule Mobilizon.GraphQL.Resolvers.AdminTest do
       %Actor{} = relay_actor = Relay.get_actor()
       insert(:follower, actor: relay_actor, target_actor: following_actor)
 
-      query = """
-      {
-        relayFollowings {
-          elements {
-            targetActor {
-              preferredUsername,
-              domain,
-            },
-            approved
-          },
-          total
-        }
-      }
-      """
-
       res =
         conn
         |> auth_conn(user_admin)
-        |> AbsintheHelpers.graphql_query(query: query)
+        |> AbsintheHelpers.graphql_query(query: @relay_followings_query)
 
       assert is_nil(res["errors"])