diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | config/description.exs | 22 | ||||
-rw-r--r-- | lib/mix/pleroma.ex | 24 | ||||
-rw-r--r-- | lib/pleroma/reverse_proxy/client/tesla.ex | 18 | ||||
-rw-r--r-- | lib/pleroma/reverse_proxy/reverse_proxy.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/api_spec/operations/chat_operation.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/api_spec/operations/domain_block_operation.ex | 9 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex | 10 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/status_view.ex | 24 | ||||
-rw-r--r-- | test/web/mastodon_api/controllers/domain_block_controller_test.exs | 32 | ||||
-rw-r--r-- | test/web/mastodon_api/views/status_view_test.exs | 17 |
11 files changed, 131 insertions, 33 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b1f9336a7..95f318584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - **Breaking:** Notification Settings API option for hiding push notification contents has been renamed to `hide_notification_contents` - Mastodon API: Added `pleroma.metadata.post_formats` to /api/v1/instance +- Mastodon API (legacy): Allow query parameters for `/api/v1/domain_blocks`, e.g. `/api/v1/domain_blocks?domain=badposters.zone` </details> <details> diff --git a/config/description.exs b/config/description.exs index b62d26344..c303fc878 100644 --- a/config/description.exs +++ b/config/description.exs @@ -1487,6 +1487,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_simple, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.SimplePolicy", label: "MRF Simple", type: :group, description: "Simple ingress policies", @@ -1553,6 +1554,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_activity_expiration, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy", label: "MRF Activity Expiration Policy", type: :group, description: "Adds automatic expiration to all local activities", @@ -1569,6 +1571,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_subchain, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.SubchainPolicy", label: "MRF Subchain", type: :group, description: @@ -1591,6 +1594,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_rejectnonpublic, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.RejectNonPublic", description: "RejectNonPublic drops posts with non-public visibility settings.", label: "MRF Reject Non Public", type: :group, @@ -1612,6 +1616,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_hellthread, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.HellthreadPolicy", label: "MRF Hellthread", type: :group, description: "Block messages with excessive user mentions", @@ -1637,6 +1642,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_keyword, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.KeywordPolicy", label: "MRF Keyword", type: :group, description: "Reject or Word-Replace messages with a keyword or regex", @@ -1668,6 +1674,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_mention, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.MentionPolicy", label: "MRF Mention", type: :group, description: "Block messages which mention a specific user", @@ -1684,6 +1691,7 @@ config :pleroma, :config_description, [ group: :pleroma, key: :mrf_vocabulary, tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.VocabularyPolicy", label: "MRF Vocabulary", type: :group, description: "Filter messages which belong to certain activity vocabularies", @@ -1707,6 +1715,8 @@ config :pleroma, :config_description, [ # %{ # group: :pleroma, # key: :mrf_user_allowlist, + # tab: :mrf, + # related_policy: "Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy", # type: :map, # description: # "The keys in this section are the domain names that the policy should apply to." <> @@ -2286,13 +2296,13 @@ config :pleroma, :config_description, [ children: [ %{ key: :class, - type: [:string, false], + type: [:string, :boolean], description: "Specify the class to be added to the generated link. Disable to clear.", suggestions: ["auto-linker", false] }, %{ key: :rel, - type: [:string, false], + type: [:string, :boolean], description: "Override the rel attribute. Disable to clear.", suggestions: ["ugc", "noopener noreferrer", false] }, @@ -2303,7 +2313,7 @@ config :pleroma, :config_description, [ }, %{ key: :truncate, - type: [:integer, false], + type: [:integer, :boolean], description: "Set to a number to truncate URLs longer than the number. Truncated URLs will end in `...`", suggestions: [15, false] @@ -2971,8 +2981,9 @@ config :pleroma, :config_description, [ }, %{ group: :pleroma, - tab: :mrf, key: :mrf_normalize_markup, + tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.NormalizeMarkup", label: "MRF Normalize Markup", description: "MRF NormalizeMarkup settings. Scrub configured hypertext markup.", type: :group, @@ -3167,8 +3178,9 @@ config :pleroma, :config_description, [ %{ group: :pleroma, key: :mrf_object_age, - label: "MRF Object Age", tab: :mrf, + related_policy: "Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy", + label: "MRF Object Age", type: :group, description: "Rejects or delists posts based on their timestamp deviance from your server's clock.", diff --git a/lib/mix/pleroma.ex b/lib/mix/pleroma.ex index 9f0bf6ecb..074492a46 100644 --- a/lib/mix/pleroma.ex +++ b/lib/mix/pleroma.ex @@ -24,8 +24,10 @@ defmodule Mix.Pleroma do Application.put_env(:logger, :console, level: :debug) end + adapter = Application.get_env(:tesla, :adapter) + apps = - if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Gun do + if adapter == Tesla.Adapter.Gun do [:gun | @apps] else [:hackney | @apps] @@ -33,11 +35,14 @@ defmodule Mix.Pleroma do Enum.each(apps, &Application.ensure_all_started/1) - children = [ - Pleroma.Repo, - {Pleroma.Config.TransferTask, false}, - Pleroma.Web.Endpoint - ] + children = + [ + Pleroma.Repo, + {Pleroma.Config.TransferTask, false}, + Pleroma.Web.Endpoint, + {Oban, Pleroma.Config.get(Oban)} + ] ++ + http_children(adapter) cachex_children = Enum.map(@cachex_children, &Pleroma.Application.build_cachex(&1, [])) @@ -115,4 +120,11 @@ defmodule Mix.Pleroma do def escape_sh_path(path) do ~S(') <> String.replace(path, ~S('), ~S(\')) <> ~S(') end + + defp http_children(Tesla.Adapter.Gun) do + Pleroma.Gun.ConnectionPool.children() ++ + [{Task, &Pleroma.HTTP.AdapterHelper.Gun.limiter_setup/0}] + end + + defp http_children(_), do: [] end diff --git a/lib/pleroma/reverse_proxy/client/tesla.ex b/lib/pleroma/reverse_proxy/client/tesla.ex index 65785445d..d5a339681 100644 --- a/lib/pleroma/reverse_proxy/client/tesla.ex +++ b/lib/pleroma/reverse_proxy/client/tesla.ex @@ -5,6 +5,8 @@ defmodule Pleroma.ReverseProxy.Client.Tesla do @behaviour Pleroma.ReverseProxy.Client + alias Pleroma.Gun.ConnectionPool + @type headers() :: [{String.t(), String.t()}] @type status() :: pos_integer() @@ -31,6 +33,8 @@ defmodule Pleroma.ReverseProxy.Client.Tesla do if is_map(response.body) and method != :head do {:ok, response.status, response.headers, response.body} else + conn_pid = response.opts[:adapter][:conn] + ConnectionPool.release_conn(conn_pid) {:ok, response.status, response.headers} end else @@ -41,15 +45,8 @@ defmodule Pleroma.ReverseProxy.Client.Tesla do @impl true @spec stream_body(map()) :: {:ok, binary(), map()} | {:error, atom() | String.t()} | :done | no_return() - def stream_body(%{pid: pid, opts: opts, fin: true}) do - # if connection was reused, but in tesla were redirects, - # tesla returns new opened connection, which must be closed manually - if opts[:old_conn], do: Tesla.Adapter.Gun.close(pid) - # if there were redirects we need to checkout old conn - conn = opts[:old_conn] || opts[:conn] - - if conn, do: :ok = Pleroma.Gun.ConnectionPool.release_conn(conn) - + def stream_body(%{pid: pid, fin: true}) do + ConnectionPool.release_conn(pid) :done end @@ -74,8 +71,7 @@ defmodule Pleroma.ReverseProxy.Client.Tesla do @impl true @spec close(map) :: :ok | no_return() def close(%{pid: pid}) do - adapter = check_adapter() - adapter.close(pid) + ConnectionPool.release_conn(pid) end defp check_adapter do diff --git a/lib/pleroma/reverse_proxy/reverse_proxy.ex b/lib/pleroma/reverse_proxy/reverse_proxy.ex index 28ad4c846..0de4e2309 100644 --- a/lib/pleroma/reverse_proxy/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy/reverse_proxy.ex @@ -165,6 +165,9 @@ defmodule Pleroma.ReverseProxy do {:ok, code, _, _} -> {:error, {:invalid_http_response, code}} + {:ok, code, _} -> + {:error, {:invalid_http_response, code}} + {:error, error} -> {:error, error} end diff --git a/lib/pleroma/web/api_spec/operations/chat_operation.ex b/lib/pleroma/web/api_spec/operations/chat_operation.ex index cf299bfc2..b1a0d26ab 100644 --- a/lib/pleroma/web/api_spec/operations/chat_operation.ex +++ b/lib/pleroma/web/api_spec/operations/chat_operation.ex @@ -300,11 +300,11 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do "content" => "Check this out :firefox:", "id" => "13", "chat_id" => "1", - "actor_id" => "someflakeid", + "account_id" => "someflakeid", "unread" => false }, %{ - "actor_id" => "someflakeid", + "account_id" => "someflakeid", "content" => "Whats' up?", "id" => "12", "chat_id" => "1", diff --git a/lib/pleroma/web/api_spec/operations/domain_block_operation.ex b/lib/pleroma/web/api_spec/operations/domain_block_operation.ex index 049bcf931..1e0da8209 100644 --- a/lib/pleroma/web/api_spec/operations/domain_block_operation.ex +++ b/lib/pleroma/web/api_spec/operations/domain_block_operation.ex @@ -31,6 +31,7 @@ defmodule Pleroma.Web.ApiSpec.DomainBlockOperation do } end + # Supporting domain query parameter is deprecated in Mastodon API def create_operation do %Operation{ tags: ["domain_blocks"], @@ -45,11 +46,13 @@ defmodule Pleroma.Web.ApiSpec.DomainBlockOperation do """, operationId: "DomainBlockController.create", requestBody: domain_block_request(), + parameters: [Operation.parameter(:domain, :query, %Schema{type: :string}, "Domain name")], security: [%{"oAuth" => ["follow", "write:blocks"]}], responses: %{200 => empty_object_response()} } end + # Supporting domain query parameter is deprecated in Mastodon API def delete_operation do %Operation{ tags: ["domain_blocks"], @@ -57,6 +60,7 @@ defmodule Pleroma.Web.ApiSpec.DomainBlockOperation do description: "Remove a domain block, if it exists in the user's array of blocked domains.", operationId: "DomainBlockController.delete", requestBody: domain_block_request(), + parameters: [Operation.parameter(:domain, :query, %Schema{type: :string}, "Domain name")], security: [%{"oAuth" => ["follow", "write:blocks"]}], responses: %{ 200 => Operation.response("Empty object", "application/json", %Schema{type: :object}) @@ -71,10 +75,9 @@ defmodule Pleroma.Web.ApiSpec.DomainBlockOperation do type: :object, properties: %{ domain: %Schema{type: :string} - }, - required: [:domain] + } }, - required: true, + required: false, example: %{ "domain" => "facebook.com" } diff --git a/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex b/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex index 825b231ab..9c2d093cd 100644 --- a/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex @@ -32,9 +32,19 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockController do json(conn, %{}) end + def create(%{assigns: %{user: blocker}} = conn, %{domain: domain}) do + User.block_domain(blocker, domain) + json(conn, %{}) + end + @doc "DELETE /api/v1/domain_blocks" def delete(%{assigns: %{user: blocker}, body_params: %{domain: domain}} = conn, _params) do User.unblock_domain(blocker, domain) json(conn, %{}) end + + def delete(%{assigns: %{user: blocker}} = conn, %{domain: domain}) do + User.unblock_domain(blocker, domain) + json(conn, %{}) + end end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index fa9d695f3..91b41ef59 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -297,13 +297,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do emoji_reactions = with %{data: %{"reactions" => emoji_reactions}} <- object do - Enum.map(emoji_reactions, fn [emoji, users] -> - %{ - name: emoji, - count: length(users), - me: !!(opts[:for] && opts[:for].ap_id in users) - } + Enum.map(emoji_reactions, fn + [emoji, users] when is_list(users) -> + build_emoji_map(emoji, users, opts[:for]) + + {emoji, users} when is_list(users) -> + build_emoji_map(emoji, users, opts[:for]) + + _ -> + nil end) + |> Enum.reject(&is_nil/1) else _ -> [] end @@ -545,4 +549,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do defp pinned?(%Activity{id: id}, %User{pinned_activities: pinned_activities}), do: id in pinned_activities + + defp build_emoji_map(emoji, users, current_user) do + %{ + name: emoji, + count: length(users), + me: !!(current_user && current_user.ap_id in users) + } + end end diff --git a/test/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/web/mastodon_api/controllers/domain_block_controller_test.exs index 01a24afcf..664654500 100644 --- a/test/web/mastodon_api/controllers/domain_block_controller_test.exs +++ b/test/web/mastodon_api/controllers/domain_block_controller_test.exs @@ -32,6 +32,38 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do refute User.blocks?(user, other_user) end + test "blocking a domain via query params" do + %{user: user, conn: conn} = oauth_access(["write:blocks"]) + other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"}) + + ret_conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/domain_blocks?domain=dogwhistle.zone") + + assert %{} == json_response_and_validate_schema(ret_conn, 200) + user = User.get_cached_by_ap_id(user.ap_id) + assert User.blocks?(user, other_user) + end + + test "unblocking a domain via query params" do + %{user: user, conn: conn} = oauth_access(["write:blocks"]) + other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"}) + + User.block_domain(user, "dogwhistle.zone") + user = refresh_record(user) + assert User.blocks?(user, other_user) + + ret_conn = + conn + |> put_req_header("content-type", "application/json") + |> delete("/api/v1/domain_blocks?domain=dogwhistle.zone") + + assert %{} == json_response_and_validate_schema(ret_conn, 200) + user = User.get_cached_by_ap_id(user.ap_id) + refute User.blocks?(user, other_user) + end + test "getting a list of domain blocks" do %{user: user, conn: conn} = oauth_access(["read:blocks"]) diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs index d97d818bb..8703d5ba7 100644 --- a/test/web/mastodon_api/views/status_view_test.exs +++ b/test/web/mastodon_api/views/status_view_test.exs @@ -56,6 +56,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do ] end + test "works correctly with badly formatted emojis" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{status: "yo"}) + + activity + |> Object.normalize(false) + |> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}}) + + activity = Activity.get_by_id(activity.id) + + status = StatusView.render("show.json", activity: activity, for: user) + + assert status[:pleroma][:emoji_reactions] == [ + %{name: "☕", count: 1, me: true} + ] + end + test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do user = insert(:user) |