Merge branch 'feat/client_app_details' into 'develop'
authorlain <lain@soykaf.club>
Sun, 28 Feb 2021 16:17:34 +0000 (16:17 +0000)
committerlain <lain@soykaf.club>
Sun, 28 Feb 2021 16:17:34 +0000 (16:17 +0000)
Support application field

See merge request pleroma/pleroma!3311

CHANGELOG.md
lib/pleroma/constants.ex
lib/pleroma/user.ex
lib/pleroma/web/api_spec/schemas/status.ex
lib/pleroma/web/common_api/activity_draft.ex
lib/pleroma/web/mastodon_api/controllers/status_controller.ex
lib/pleroma/web/mastodon_api/views/status_view.ex
priv/repo/migrations/20210218223811_add_disclose_client_to_users.exs [new file with mode: 0644]
test/pleroma/web/activity_pub/transmogrifier_test.exs
test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
test/pleroma/web/mastodon_api/views/status_view_test.exs

index 508a6ea1543277d00174bcdf4a2d4708084b9d02..c4837c9553b763cbaa458ae710e8a003e7e00f4b 100644 (file)
@@ -59,6 +59,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Ability to define custom HTTP headers per each frontend
 - MRF (`NoEmptyPolicy`): New MRF Policy which will deny empty statuses or statuses of only mentions from being created by local users
 - New users will receive a simple email confirming their registration if no other emails will be dispatched. (e.g., Welcome, Confirmation, or Approval Required)
+- The `application` metadata returned with statuses is no longer hardcoded. Apps that want to display these details will now have valid data for new posts after this change.
 
 <details>
   <summary>API Changes</summary>
index a40741ba606ecf54e001c989b255203793ba7816..9ee836d5d8a4c58784aa21003e2c0c8be0b10b2b 100644 (file)
@@ -18,7 +18,8 @@ defmodule Pleroma.Constants do
       "emoji",
       "context_id",
       "deleted_activity_id",
-      "pleroma_internal"
+      "pleroma_internal",
+      "application"
     ]
   )
 
index 51f5bc8ea1a5dd3c404cae92f9709e59d6ec6371..9942617d87d655e9ff507e2a1074b5ecf83b2856 100644 (file)
@@ -147,6 +147,7 @@ defmodule Pleroma.User do
     field(:shared_inbox, :string)
     field(:accepts_chat_messages, :boolean, default: nil)
     field(:last_active_at, :naive_datetime)
+    field(:disclose_client, :boolean, default: true)
 
     embeds_one(
       :notification_settings,
@@ -513,7 +514,8 @@ defmodule Pleroma.User do
         :pleroma_settings_store,
         :is_discoverable,
         :actor_type,
-        :accepts_chat_messages
+        :accepts_chat_messages,
+        :disclose_client
       ]
     )
     |> unique_constraint(:nickname)
index 61ebd8089c7a6256cf4df7ffb7823108b3e888cf..42fa987181946851bedc22c9546da5807faf8471 100644 (file)
@@ -23,9 +23,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
       application: %Schema{
         description: "The application used to post this status",
         type: :object,
+        nullable: true,
         properties: %{
           name: %Schema{type: :string},
-          website: %Schema{type: :string, nullable: true, format: :uri}
+          website: %Schema{type: :string, format: :uri}
         }
       },
       bookmarked: %Schema{type: :boolean, description: "Have you bookmarked this status?"},
@@ -291,7 +292,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
         "url" => "http://localhost:4001/users/nick6",
         "username" => "nick6"
       },
-      "application" => %{"name" => "Web", "website" => nil},
+      "application" => nil,
       "bookmarked" => false,
       "card" => nil,
       "content" => "foobar",
index fb059c27cb61295c0b821616cdbaf2233d1382c1..d7dcdad9019ca423c98993c37957b704be18209c 100644 (file)
@@ -190,6 +190,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do
       Utils.make_note_data(draft)
       |> Map.put("emoji", emoji)
       |> Map.put("source", draft.status)
+      |> Map.put("application", draft.params[:application])
 
     %__MODULE__{draft | object: object}
   end
index 4cf2ee35caa0a08e157d509ece83e5b1f6b71feb..b8a7b2a0afd5fa9aff6ecd6d3a731c2339d43b64 100644 (file)
@@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.MastodonAPI.AccountView
   alias Pleroma.Web.MastodonAPI.ScheduledActivityView
+  alias Pleroma.Web.OAuth.Token
   alias Pleroma.Web.Plugs.OAuthScopesPlug
   alias Pleroma.Web.Plugs.RateLimiter
 
@@ -138,7 +139,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
         _
       )
       when not is_nil(scheduled_at) do
-    params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+    params =
+      Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+      |> put_application(conn)
 
     attrs = %{
       params: Map.new(params, fn {key, value} -> {to_string(key), value} end),
@@ -162,7 +165,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
 
   # Creates a regular status
   def create(%{assigns: %{user: user}, body_params: %{status: _} = params} = conn, _) do
-    params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+    params =
+      Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id])
+      |> put_application(conn)
 
     with {:ok, activity} <- CommonAPI.post(user, params) do
       try_render(conn, "show.json",
@@ -414,4 +419,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
       as: :activity
     )
   end
+
+  defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do
+    if user.disclose_client do
+      %{client_name: client_name, website: website} = Repo.preload(token, :app).app
+      Map.put(params, :application, %{type: "Application", name: client_name, url: website})
+    else
+      Map.put(params, :application, nil)
+    end
+  end
+
+  defp put_application(params, _), do: Map.put(params, :application, nil)
 end
index 2cd6732fe0a5ee9cac257cc5dd9c5ca863936814..792197a4a4b49ccd85f70df99ada329c7f859e88 100644 (file)
@@ -180,10 +180,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
       media_attachments: reblogged[:media_attachments] || [],
       mentions: mentions,
       tags: reblogged[:tags] || [],
-      application: %{
-        name: "Web",
-        website: nil
-      },
+      application: build_application(activity_object.data["application"]),
       language: nil,
       emojis: [],
       pleroma: %{
@@ -348,10 +345,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
       poll: render(PollView, "show.json", object: object, for: opts[:for]),
       mentions: mentions,
       tags: build_tags(tags),
-      application: %{
-        name: "Web",
-        website: nil
-      },
+      application: build_application(object.data["application"]),
       language: nil,
       emojis: build_emojis(object.data["emoji"]),
       pleroma: %{
@@ -540,4 +534,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
       me: !!(current_user && current_user.ap_id in users)
     }
   end
+
+  @spec build_application(map() | nil) :: map() | nil
+  defp build_application(%{type: _type, name: name, url: url}), do: %{name: name, website: url}
+  defp build_application(_), do: nil
 end
diff --git a/priv/repo/migrations/20210218223811_add_disclose_client_to_users.exs b/priv/repo/migrations/20210218223811_add_disclose_client_to_users.exs
new file mode 100644 (file)
index 0000000..37c5776
--- /dev/null
@@ -0,0 +1,9 @@
+defmodule Pleroma.Repo.Migrations.AddDiscloseClientToUsers do
+  use Ecto.Migration
+
+  def change do
+    alter table(:users) do
+      add(:disclose_client, :boolean, default: true)
+    end
+  end
+end
index 7c97fa8f880a3faf92aa130d1fee2a3865c1cb01..f6a8cbb6fd971c1ba23cf7ae158bdd22bbe05e76 100644 (file)
@@ -202,7 +202,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
     test "it strips internal fields" do
       user = insert(:user)
 
-      {:ok, activity} = CommonAPI.post(user, %{status: "#2hu :firefox:"})
+      {:ok, activity} =
+        CommonAPI.post(user, %{
+          status: "#2hu :firefox:",
+          application: %{type: "Application", name: "TestClient", url: "https://pleroma.social"}
+        })
+
+      # Ensure injected application data made it into the activity
+      # as we don't have a Token to derive it from, otherwise it will
+      # be nil and the test will pass
+      assert %{
+               type: "Application",
+               name: "TestClient",
+               url: "https://pleroma.social"
+             } == activity.object.data["application"]
 
       {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
 
@@ -213,6 +226,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert is_nil(modified["object"]["announcements"])
       assert is_nil(modified["object"]["announcement_count"])
       assert is_nil(modified["object"]["context_id"])
+      assert is_nil(modified["object"]["application"])
     end
 
     test "it strips internal fields of article" do
index c59b156bf44c929430922dbb5b66acdff4e5a67d..dd2f306b793e2d5a5af936464fbb6e00b671d897 100644 (file)
@@ -357,6 +357,50 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
       assert activity.data["to"] == [user2.ap_id]
       assert activity.data["cc"] == []
     end
+
+    test "discloses application metadata when enabled" do
+      user = insert(:user, disclose_client: true)
+      %{user: _user, token: token, conn: conn} = oauth_access(["write:statuses"], user: user)
+
+      %Pleroma.Web.OAuth.Token{
+        app: %Pleroma.Web.OAuth.App{
+          client_name: _app_name,
+          website: _app_website
+        }
+      } = token
+
+      result =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/v1/statuses", %{
+          "status" => "cofe is my copilot"
+        })
+
+      assert %{
+               "content" => "cofe is my copilot",
+               "application" => %{
+                 "name" => app_name,
+                 "website" => app_website
+               }
+             } = json_response_and_validate_schema(result, 200)
+    end
+
+    test "hides application metadata when disabled" do
+      user = insert(:user, disclose_client: false)
+      %{user: _user, token: _token, conn: conn} = oauth_access(["write:statuses"], user: user)
+
+      result =
+        conn
+        |> put_req_header("content-type", "application/json")
+        |> post("/api/v1/statuses", %{
+          "status" => "club mate is my wingman"
+        })
+
+      assert %{
+               "content" => "club mate is my wingman",
+               "application" => nil
+             } = json_response_and_validate_schema(result, 200)
+    end
   end
 
   describe "posting scheduled statuses" do
index ed59cf285652cab805ea999b225c8d672cc26975..2de3afc4fb15f59dfb3f2b58ba584409fd09f678 100644 (file)
@@ -266,10 +266,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
           url: "http://localhost:4001/tag/#{object_data["tag"]}"
         }
       ],
-      application: %{
-        name: "Web",
-        website: nil
-      },
+      application: nil,
       language: nil,
       emojis: [
         %{