Merge branch 'feat/client_app_details' into 'develop'
Support application field See merge request pleroma/pleroma!3311
This commit is contained in:
commit
e6a14e1cd1
11 changed files with 103 additions and 19 deletions
|
@ -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
|
- 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
|
- 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)
|
- 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>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
|
|
|
@ -18,7 +18,8 @@ defmodule Pleroma.Constants do
|
||||||
"emoji",
|
"emoji",
|
||||||
"context_id",
|
"context_id",
|
||||||
"deleted_activity_id",
|
"deleted_activity_id",
|
||||||
"pleroma_internal"
|
"pleroma_internal",
|
||||||
|
"application"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ defmodule Pleroma.User do
|
||||||
field(:shared_inbox, :string)
|
field(:shared_inbox, :string)
|
||||||
field(:accepts_chat_messages, :boolean, default: nil)
|
field(:accepts_chat_messages, :boolean, default: nil)
|
||||||
field(:last_active_at, :naive_datetime)
|
field(:last_active_at, :naive_datetime)
|
||||||
|
field(:disclose_client, :boolean, default: true)
|
||||||
|
|
||||||
embeds_one(
|
embeds_one(
|
||||||
:notification_settings,
|
:notification_settings,
|
||||||
|
@ -513,7 +514,8 @@ def update_changeset(struct, params \\ %{}) do
|
||||||
:pleroma_settings_store,
|
:pleroma_settings_store,
|
||||||
:is_discoverable,
|
:is_discoverable,
|
||||||
:actor_type,
|
:actor_type,
|
||||||
:accepts_chat_messages
|
:accepts_chat_messages,
|
||||||
|
:disclose_client
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|> unique_constraint(:nickname)
|
|> unique_constraint(:nickname)
|
||||||
|
|
|
@ -23,9 +23,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
|
||||||
application: %Schema{
|
application: %Schema{
|
||||||
description: "The application used to post this status",
|
description: "The application used to post this status",
|
||||||
type: :object,
|
type: :object,
|
||||||
|
nullable: true,
|
||||||
properties: %{
|
properties: %{
|
||||||
name: %Schema{type: :string},
|
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?"},
|
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",
|
"url" => "http://localhost:4001/users/nick6",
|
||||||
"username" => "nick6"
|
"username" => "nick6"
|
||||||
},
|
},
|
||||||
"application" => %{"name" => "Web", "website" => nil},
|
"application" => nil,
|
||||||
"bookmarked" => false,
|
"bookmarked" => false,
|
||||||
"card" => nil,
|
"card" => nil,
|
||||||
"content" => "foobar",
|
"content" => "foobar",
|
||||||
|
|
|
@ -190,6 +190,7 @@ defp object(draft) do
|
||||||
Utils.make_note_data(draft)
|
Utils.make_note_data(draft)
|
||||||
|> Map.put("emoji", emoji)
|
|> Map.put("emoji", emoji)
|
||||||
|> Map.put("source", draft.status)
|
|> Map.put("source", draft.status)
|
||||||
|
|> Map.put("application", draft.params[:application])
|
||||||
|
|
||||||
%__MODULE__{draft | object: object}
|
%__MODULE__{draft | object: object}
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.MastodonAPI.AccountView
|
alias Pleroma.Web.MastodonAPI.AccountView
|
||||||
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
|
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
|
||||||
|
alias Pleroma.Web.OAuth.Token
|
||||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||||
alias Pleroma.Web.Plugs.RateLimiter
|
alias Pleroma.Web.Plugs.RateLimiter
|
||||||
|
|
||||||
|
@ -138,7 +139,9 @@ def create(
|
||||||
_
|
_
|
||||||
)
|
)
|
||||||
when not is_nil(scheduled_at) 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 = %{
|
attrs = %{
|
||||||
params: Map.new(params, fn {key, value} -> {to_string(key), value} end),
|
params: Map.new(params, fn {key, value} -> {to_string(key), value} end),
|
||||||
|
@ -162,7 +165,9 @@ def create(
|
||||||
|
|
||||||
# Creates a regular status
|
# Creates a regular status
|
||||||
def create(%{assigns: %{user: user}, body_params: %{status: _} = params} = conn, _) do
|
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
|
with {:ok, activity} <- CommonAPI.post(user, params) do
|
||||||
try_render(conn, "show.json",
|
try_render(conn, "show.json",
|
||||||
|
@ -414,4 +419,15 @@ def bookmarks(%{assigns: %{user: user}} = conn, params) do
|
||||||
as: :activity
|
as: :activity
|
||||||
)
|
)
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -180,10 +180,7 @@ def render(
|
||||||
media_attachments: reblogged[:media_attachments] || [],
|
media_attachments: reblogged[:media_attachments] || [],
|
||||||
mentions: mentions,
|
mentions: mentions,
|
||||||
tags: reblogged[:tags] || [],
|
tags: reblogged[:tags] || [],
|
||||||
application: %{
|
application: build_application(activity_object.data["application"]),
|
||||||
name: "Web",
|
|
||||||
website: nil
|
|
||||||
},
|
|
||||||
language: nil,
|
language: nil,
|
||||||
emojis: [],
|
emojis: [],
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
|
@ -348,10 +345,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
||||||
poll: render(PollView, "show.json", object: object, for: opts[:for]),
|
poll: render(PollView, "show.json", object: object, for: opts[:for]),
|
||||||
mentions: mentions,
|
mentions: mentions,
|
||||||
tags: build_tags(tags),
|
tags: build_tags(tags),
|
||||||
application: %{
|
application: build_application(object.data["application"]),
|
||||||
name: "Web",
|
|
||||||
website: nil
|
|
||||||
},
|
|
||||||
language: nil,
|
language: nil,
|
||||||
emojis: build_emojis(object.data["emoji"]),
|
emojis: build_emojis(object.data["emoji"]),
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
|
@ -540,4 +534,8 @@ defp build_emoji_map(emoji, users, current_user) do
|
||||||
me: !!(current_user && current_user.ap_id in users)
|
me: !!(current_user && current_user.ap_id in users)
|
||||||
}
|
}
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -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
|
|
@ -202,7 +202,20 @@ test "it strips internal hashtag data" do
|
||||||
test "it strips internal fields" do
|
test "it strips internal fields" do
|
||||||
user = insert(:user)
|
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)
|
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
|
||||||
|
|
||||||
|
@ -213,6 +226,7 @@ test "it strips internal fields" do
|
||||||
assert is_nil(modified["object"]["announcements"])
|
assert is_nil(modified["object"]["announcements"])
|
||||||
assert is_nil(modified["object"]["announcement_count"])
|
assert is_nil(modified["object"]["announcement_count"])
|
||||||
assert is_nil(modified["object"]["context_id"])
|
assert is_nil(modified["object"]["context_id"])
|
||||||
|
assert is_nil(modified["object"]["application"])
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it strips internal fields of article" do
|
test "it strips internal fields of article" do
|
||||||
|
|
|
@ -357,6 +357,50 @@ test "posting a direct status", %{conn: conn} do
|
||||||
assert activity.data["to"] == [user2.ap_id]
|
assert activity.data["to"] == [user2.ap_id]
|
||||||
assert activity.data["cc"] == []
|
assert activity.data["cc"] == []
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe "posting scheduled statuses" do
|
describe "posting scheduled statuses" do
|
||||||
|
|
|
@ -266,10 +266,7 @@ test "a note activity" do
|
||||||
url: "http://localhost:4001/tag/#{object_data["tag"]}"
|
url: "http://localhost:4001/tag/#{object_data["tag"]}"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
application: %{
|
application: nil,
|
||||||
name: "Web",
|
|
||||||
website: nil
|
|
||||||
},
|
|
||||||
language: nil,
|
language: nil,
|
||||||
emojis: [
|
emojis: [
|
||||||
%{
|
%{
|
||||||
|
|
Loading…
Reference in a new issue