From 9ad045fd587f83386d9582136c971dbcd4410b67 Mon Sep 17 00:00:00 2001
From: Roger Braun <roger@rogerbraun.net>
Date: Thu, 23 Mar 2017 15:51:34 +0100
Subject: [PATCH] Return user specific json for logged in users.

---
 lib/pleroma/user.ex                           |  4 +++
 .../representers/activity_representer.ex      |  4 +--
 .../representers/user_representer.ex          | 13 +++++--
 lib/pleroma/web/twitter_api/twitter_api.ex    | 10 +++---
 .../web/twitter_api/twitter_api_controller.ex | 13 ++++---
 test/user_test.exs                            |  8 +++++
 .../activity_representer_test.exs             |  6 ++--
 .../representers/user_representer_test.exs    | 34 ++++++++++++++-----
 .../twitter_api_controller_test.exs           |  3 +-
 test/web/twitter_api/twitter_api_test.exs     |  6 ++--
 10 files changed, 72 insertions(+), 29 deletions(-)

diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index a10b43b78..67f590ee8 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -53,4 +53,8 @@ defmodule Pleroma.User do
     |> follow_changeset(%{following: following})
     |> Repo.update
   end
+
+  def following?(%User{} = follower, %User{} = followed) do
+    Enum.member?(follower.following, User.ap_followers(followed))
+  end
 end
diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
index 171878162..a0f20c37c 100644
--- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex
+++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
@@ -3,12 +3,12 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
   alias Pleroma.Web.TwitterAPI.Representers.UserRepresenter
   alias Pleroma.Activity
 
-  def to_map(%Activity{} = activity, %{user: user}) do
+  def to_map(%Activity{} = activity, %{user: user} = opts) do
     content = get_in(activity.data, ["object", "content"])
     published = get_in(activity.data, ["object", "published"])
     %{
       "id" => activity.id,
-      "user" => UserRepresenter.to_map(user),
+      "user" => UserRepresenter.to_map(user, opts),
       "attentions" => [],
       "statusnet_html" => content,
       "text" => content,
diff --git a/lib/pleroma/web/twitter_api/representers/user_representer.ex b/lib/pleroma/web/twitter_api/representers/user_representer.ex
index 079e25021..8875d26ff 100644
--- a/lib/pleroma/web/twitter_api/representers/user_representer.ex
+++ b/lib/pleroma/web/twitter_api/representers/user_representer.ex
@@ -1,14 +1,23 @@
 defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenter do
   use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
+  alias Pleroma.User
+
+  def to_map(user, opts \\ %{}) do
 
-  def to_map(user, options) do
     image = "https://placehold.it/48x48"
+
+    following = if opts[:for] do
+      User.following?(opts[:for], user)
+    else
+      false
+    end
+
     map = %{
       "id" => user.id,
       "name" => user.name,
       "screen_name" => user.nickname,
       "description" => user.bio,
-      "following" => false,
+      "following" => following,
       # Fake fields
       "favourites_count" => 0,
       "statuses_count" => 0,
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 2ef679397..58fd51a62 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -26,12 +26,12 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
 
   def fetch_friend_statuses(user, opts \\ %{}) do
     ActivityPub.fetch_activities(user.following, opts)
-    |> activities_to_statuses
+    |> activities_to_statuses(%{for: user})
   end
 
-  def fetch_public_statuses(opts \\ %{}) do
+  def fetch_public_statuses(user, opts \\ %{}) do
     ActivityPub.fetch_public_activities(opts)
-    |> activities_to_statuses
+    |> activities_to_statuses(%{for: user})
   end
 
   def follow(%User{} = follower, followed_id) do
@@ -50,11 +50,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
     end
   end
 
-  defp activities_to_statuses(activities) do
+  defp activities_to_statuses(activities, opts) do
     Enum.map(activities, fn(activity) ->
       actor = get_in(activity.data, ["actor"])
       user = Repo.get_by!(User, ap_id: actor)
-      ActivityRepresenter.to_map(activity, %{user: user})
+      ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user}))
     end)
   end
 end
diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
index d574f1003..42485933b 100644
--- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
@@ -4,7 +4,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
   alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter}
 
   def verify_credentials(%{assigns: %{user: user}} = conn, _params) do
-    response = user |> UserRepresenter.to_json
+    response = user |> UserRepresenter.to_json(%{for: user})
 
     conn
     |> json_reply(200, response)
@@ -16,8 +16,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
     |> json_reply(200, ActivityRepresenter.to_json(activity, %{user: user}))
   end
 
-  def public_timeline(conn, params) do
-    statuses = TwitterAPI.fetch_public_statuses(params)
+  def public_timeline(%{assigns: %{user: user}} = conn, params) do
+    statuses = TwitterAPI.fetch_public_statuses(user, params)
     {:ok, json} = Poison.encode(statuses)
 
     conn
@@ -35,22 +35,21 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
   def follow(%{assigns: %{user: user}} = conn, %{ "user_id" => followed_id }) do
     { :ok, _user, follower } = TwitterAPI.follow(user, followed_id)
 
-    response = follower |> UserRepresenter.to_json
+    response = follower |> UserRepresenter.to_json(%{for: user})
 
     conn
     |> json_reply(200, response)
   end
 
   def unfollow(%{assigns: %{user: user}} = conn, %{ "user_id" => followed_id }) do
-    { :ok, _user, follower } = TwitterAPI.unfollow(user, followed_id)
+    { :ok, user, follower } = TwitterAPI.unfollow(user, followed_id)
 
-    response = follower |> UserRepresenter.to_json
+    response = follower |> UserRepresenter.to_json(%{for: user})
 
     conn
     |> json_reply(200, response)
   end
 
-
   defp json_reply(conn, status, json) do
     conn
     |> put_resp_content_type("application/json")
diff --git a/test/user_test.exs b/test/user_test.exs
index e11bade93..f41063e9c 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -45,4 +45,12 @@ defmodule Pleroma.UserTest do
 
     assert user.following == []
   end
+
+  test "test if a user is following another user" do
+    { :ok, followed } = UserBuilder.insert(%{nickname: "guy"})
+    { :ok, user } = UserBuilder.insert(%{following: [User.ap_followers(followed)]})
+
+    assert User.following?(user, followed)
+    refute User.following?(followed, user)
+  end
 end
diff --git a/test/web/twitter_api/representers/activity_representer_test.exs b/test/web/twitter_api/representers/activity_representer_test.exs
index ecfd5a73f..d40455c89 100644
--- a/test/web/twitter_api/representers/activity_representer_test.exs
+++ b/test/web/twitter_api/representers/activity_representer_test.exs
@@ -6,6 +6,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
 
   test "an activity" do
     {:ok, user} = UserBuilder.insert
+    {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
+
     content = "Some content"
     date = DateTime.utc_now() |> DateTime.to_iso8601
 
@@ -30,7 +32,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
 
     expected_status = %{
       "id" => activity.id,
-      "user" => UserRepresenter.to_map(user),
+      "user" => UserRepresenter.to_map(user, %{for: follower}),
       "is_local" => true,
       "attentions" => [],
       "statusnet_html" => content,
@@ -39,6 +41,6 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
       "created_at" => date
     }
 
-    assert ActivityRepresenter.to_map(activity, %{user: user}) == expected_status
+    assert ActivityRepresenter.to_map(activity, %{user: user, for: follower}) == expected_status
   end
 end
diff --git a/test/web/twitter_api/representers/user_representer_test.exs b/test/web/twitter_api/representers/user_representer_test.exs
index f08e392f9..76e3bd6e6 100644
--- a/test/web/twitter_api/representers/user_representer_test.exs
+++ b/test/web/twitter_api/representers/user_representer_test.exs
@@ -3,16 +3,10 @@ defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenterTest do
 
   alias Pleroma.User
   alias Pleroma.Web.TwitterAPI.Representers.UserRepresenter
+  alias Pleroma.Builders.UserBuilder
 
   setup do
-    user = %User{
-      email: "test@example.org",
-      name: "Test Name",
-      nickname: "testname",
-      password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
-      bio: "A tester."
-    }
-    user = Repo.insert!(user)
+    {:ok, user} = UserBuilder.insert
     [user: user]
   end
 
@@ -38,4 +32,28 @@ defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenterTest do
 
     assert represented == UserRepresenter.to_map(user)
   end
+
+  test "A user for a given other follower", %{user: user} do
+    {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
+    image = "https://placehold.it/48x48"
+    represented = %{
+      "id" => user.id,
+      "name" => user.name,
+      "screen_name" => user.nickname,
+      "description" => user.bio,
+      # Fake fields
+      "favourites_count" => 0,
+      "statuses_count" => 0,
+      "friends_count" => 0,
+      "followers_count" => 0,
+      "profile_image_url" => image,
+      "profile_image_url_https" => image,
+      "profile_image_url_profile_size" => image,
+      "profile_image_url_original" => image,
+      "following" => true,
+      "rights" => %{}
+    }
+
+    assert represented == UserRepresenter.to_map(user, %{for: follower})
+  end
 end
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs
index b0a0cdb54..851d5f4a7 100644
--- a/test/web/twitter_api/twitter_api_controller_test.exs
+++ b/test/web/twitter_api/twitter_api_controller_test.exs
@@ -62,7 +62,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
     test "with credentials", %{conn: conn, user: current_user} do
       {:ok, user} = UserBuilder.insert
       activities = ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
-      ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
+      returned_activities = ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
       {:ok, other_user} = UserBuilder.insert(%{ap_id: "glimmung", nickname: "nockame"})
       ActivityBuilder.insert_list(10, %{}, %{user: other_user})
       since_id = List.last(activities).id
@@ -76,6 +76,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
       response = json_response(conn, 200)
 
       assert length(response) == 10
+      assert response == Enum.map(returned_activities, fn (activity) -> ActivityRepresenter.to_map(activity, %{user: user, for: current_user}) end)
     end
   end
 
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index 3cb3196d9..f68a49f6a 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -22,10 +22,12 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
 
   test "fetch public statuses" do
     %{ public: activity, user: user } = ActivityBuilder.public_and_non_public
-    statuses = TwitterAPI.fetch_public_statuses()
+    {:ok, follower } = UserBuilder.insert(%{name: "dude", ap_id: "idididid", following: [User.ap_followers(user)]})
+
+    statuses = TwitterAPI.fetch_public_statuses(follower)
 
     assert length(statuses) == 1
-    assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: user})
+    assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: user, for: follower})
   end
 
   test "fetch friends' statuses" do
-- 
GitLab