diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/config/deprecation_warnings.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/instances/instance.ex | 25 | ||||
-rw-r--r-- | lib/pleroma/object.ex | 43 | ||||
-rw-r--r-- | lib/pleroma/upload.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/user/info.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 15 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex | 44 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/utils.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/views/user_view.ex | 8 | ||||
-rw-r--r-- | lib/pleroma/web/federator/federator.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/status_view.ex | 17 | ||||
-rw-r--r-- | lib/pleroma/web/salmon/salmon.ex | 30 | ||||
-rw-r--r-- | lib/pleroma/web/templates/layout/app.html.eex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api_controller.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/views/user_view.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/websub/websub.ex | 14 |
17 files changed, 155 insertions, 80 deletions
diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index dc50682ee..0eb1833aa 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -12,6 +12,13 @@ defmodule Pleroma.Config.DeprecationWarnings do You are using the old configuration mechanism for the frontend. Please check config.md. """) end + + if Pleroma.Config.get(:mrf_hellthread, :threshold) do + Logger.warn(""" + !!!DEPRECATION WARNING!!! + You are using the old configuration mechanism for the hellthread filter. Please check config.md. + """) + end end def warn do diff --git a/lib/pleroma/instances/instance.ex b/lib/pleroma/instances/instance.ex index a87590d8b..4a4ca26dd 100644 --- a/lib/pleroma/instances/instance.ex +++ b/lib/pleroma/instances/instance.ex @@ -26,7 +26,7 @@ defmodule Pleroma.Instances.Instance do |> unique_constraint(:host) end - def filter_reachable([]), do: [] + def filter_reachable([]), do: %{} def filter_reachable(urls_or_hosts) when is_list(urls_or_hosts) do hosts = @@ -34,17 +34,28 @@ defmodule Pleroma.Instances.Instance do |> Enum.map(&(&1 && host(&1))) |> Enum.filter(&(to_string(&1) != "")) - unreachable_hosts = + unreachable_since_by_host = Repo.all( from(i in Instance, - where: - i.host in ^hosts and - i.unreachable_since <= ^Instances.reachability_datetime_threshold(), - select: i.host + where: i.host in ^hosts, + select: {i.host, i.unreachable_since} ) ) + |> Map.new(& &1) - Enum.filter(urls_or_hosts, &(&1 && host(&1) not in unreachable_hosts)) + reachability_datetime_threshold = Instances.reachability_datetime_threshold() + + for entry <- Enum.filter(urls_or_hosts, &is_binary/1) do + host = host(entry) + unreachable_since = unreachable_since_by_host[host] + + if !unreachable_since || + NaiveDateTime.compare(unreachable_since, reachability_datetime_threshold) == :gt do + {entry, unreachable_since} + end + end + |> Enum.filter(& &1) + |> Map.new(& &1) end def reachable?(url_or_host) when is_binary(url_or_host) do diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 1088bb5e4..7b46a3b05 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -42,24 +42,18 @@ defmodule Pleroma.Object do # Legacy objects can be mutated by anybody def authorize_mutation(%Object{}, %User{}), do: true - if Mix.env() == :test do - def get_cached_by_ap_id(ap_id) do - get_by_ap_id(ap_id) - end - else - def get_cached_by_ap_id(ap_id) do - key = "object:#{ap_id}" - - Cachex.fetch!(:object_cache, key, fn _ -> - object = get_by_ap_id(ap_id) - - if object do - {:commit, object} - else - {:ignore, object} - end - end) - end + def get_cached_by_ap_id(ap_id) do + key = "object:#{ap_id}" + + Cachex.fetch!(:object_cache, key, fn _ -> + object = get_by_ap_id(ap_id) + + if object do + {:commit, object} + else + {:ignore, object} + end + end) end def context_mapping(context) do @@ -90,4 +84,17 @@ defmodule Pleroma.Object do {:ok, object} end end + + def set_cache(%Object{data: %{"id" => ap_id}} = object) do + Cachex.put(:object_cache, "object:#{ap_id}", object) + {:ok, object} + end + + def update_and_set_cache(changeset) do + with {:ok, object} <- Repo.update(changeset) do + set_cache(object) + else + e -> e + end + end end diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index 0a19e737b..ce2a1b696 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -124,10 +124,10 @@ defmodule Pleroma.Upload do :pleroma, Pleroma.Upload, [filters: [Pleroma.Upload.Filter.Mogrify]] - :pleroma, Pleroma.Upload.Filter.Mogrify, args: "strip" + :pleroma, Pleroma.Upload.Filter.Mogrify, args: ["strip", "auto-orient"] """) - Pleroma.Config.put([Pleroma.Upload.Filter.Mogrify], args: "strip") + Pleroma.Config.put([Pleroma.Upload.Filter.Mogrify], args: ["strip", "auto-orient"]) Map.put(opts, :filters, opts.filters ++ [Pleroma.Upload.Filter.Mogrify]) else opts diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 2186190a0..c6c923aac 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -30,8 +30,7 @@ defmodule Pleroma.User.Info do field(:topic, :string, default: nil) field(:hub, :string, default: nil) field(:salmon, :string, default: nil) - field(:hide_followers, :boolean, default: false) - field(:hide_followings, :boolean, default: false) + field(:hide_network, :boolean, default: false) field(:pinned_activities, {:array, :string}, default: []) # Found in the wild @@ -144,8 +143,7 @@ defmodule Pleroma.User.Info do :no_rich_text, :default_scope, :banner, - :hide_followings, - :hide_followers, + :hide_network, :background ]) end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 06e8c3f1c..4635e7fcd 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -744,7 +744,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do public = is_public?(activity) - remote_inboxes = + reachable_inboxes_metadata = (Pleroma.Web.Salmon.remote_users(activity) ++ remote_followers) |> Enum.filter(fn user -> User.ap_enabled?(user) end) |> Enum.map(fn %{info: %{source_data: data}} -> @@ -757,17 +757,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) json = Jason.encode!(data) - Enum.each(remote_inboxes, fn inbox -> + Enum.each(reachable_inboxes_metadata, fn {inbox, unreachable_since} -> Federator.enqueue(:publish_single_ap, %{ inbox: inbox, json: json, actor: actor, - id: activity.data["id"] + id: activity.data["id"], + unreachable_since: unreachable_since }) end) end - def publish_one(%{inbox: inbox, json: json, actor: actor, id: id}) do + def publish_one(%{inbox: inbox, json: json, actor: actor, id: id} = params) do Logger.info("Federating #{id} to #{inbox}") host = URI.parse(inbox).host @@ -791,11 +792,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do {"digest", digest} ] ) do - Instances.set_reachable(inbox) + if !Map.has_key?(params, :unreachable_since) || params[:unreachable_since], + do: Instances.set_reachable(inbox) + result else {_post_result, response} -> - Instances.set_unreachable(inbox) + unless params[:unreachable_since], do: Instances.set_unreachable(inbox) {:error, response} end end diff --git a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex index a3f516ae7..4c6e612b2 100644 --- a/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/hellthread_policy.ex @@ -3,20 +3,46 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicy do + alias Pleroma.User @behaviour Pleroma.Web.ActivityPub.MRF + defp delist_message(message) do + follower_collection = User.get_cached_by_ap_id(message["actor"]).follower_address + + message + |> Map.put("to", [follower_collection]) + |> Map.put("cc", ["https://www.w3.org/ns/activitystreams#Public"]) + end + @impl true - def filter(%{"type" => "Create"} = object) do - threshold = Pleroma.Config.get([:mrf_hellthread, :threshold]) - recipients = (object["to"] || []) ++ (object["cc"] || []) - - if length(recipients) > threshold do - {:reject, nil} - else - {:ok, object} + def filter(%{"type" => "Create"} = message) do + delist_threshold = Pleroma.Config.get([:mrf_hellthread, :delist_threshold]) + + reject_threshold = + Pleroma.Config.get( + [:mrf_hellthread, :reject_threshold], + Pleroma.Config.get([:mrf_hellthread, :threshold]) + ) + + recipients = (message["to"] || []) ++ (message["cc"] || []) + + cond do + length(recipients) > reject_threshold and reject_threshold > 0 -> + {:reject, nil} + + length(recipients) > delist_threshold and delist_threshold > 0 -> + if Enum.member?(message["to"], "https://www.w3.org/ns/activitystreams#Public") or + Enum.member?(message["cc"], "https://www.w3.org/ns/activitystreams#Public") do + {:ok, delist_message(message)} + else + {:ok, message} + end + + true -> + {:ok, message} end end @impl true - def filter(object), do: {:ok, object} + def filter(message), do: {:ok, message} end diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 3b0cdfe71..4a2cc6738 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -285,7 +285,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do |> Map.put("#{property}_count", length(element)) |> Map.put("#{property}s", element), changeset <- Changeset.change(object, data: new_data), - {:ok, object} <- Repo.update(changeset), + {:ok, object} <- Object.update_and_set_cache(changeset), _ <- update_object_in_activities(object) do {:ok, object} end diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index b9588bee5..dcf681b6d 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -86,7 +86,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do query = from(user in query, select: [:ap_id]) following = Repo.all(query) - collection(following, "#{user.ap_id}/following", page, !user.info.hide_followings) + collection(following, "#{user.ap_id}/following", page, !user.info.hide_network) |> Map.merge(Utils.make_json_ld_header()) end @@ -99,7 +99,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do "id" => "#{user.ap_id}/following", "type" => "OrderedCollection", "totalItems" => length(following), - "first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_followings) + "first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_network) } |> Map.merge(Utils.make_json_ld_header()) end @@ -109,7 +109,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do query = from(user in query, select: [:ap_id]) followers = Repo.all(query) - collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers) + collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_network) |> Map.merge(Utils.make_json_ld_header()) end @@ -122,7 +122,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do "id" => "#{user.ap_id}/followers", "type" => "OrderedCollection", "totalItems" => length(followers), - "first" => collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers) + "first" => collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_network) } |> Map.merge(Utils.make_json_ld_header()) end diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index 46f7a4973..bb7676cf0 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -124,8 +124,8 @@ defmodule Pleroma.Web.Federator do end end - def handle(:publish_single_salmon, {user_or_url, feed, poster}) do - Salmon.send_to_user(user_or_url, feed, poster) + def handle(:publish_single_salmon, params) do + Salmon.send_to_user(params) end def handle(:publish_single_ap, params) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 85769c3d7..7f3fbff4a 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -605,7 +605,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do followers = cond do for_user && user.id == for_user.id -> followers - user.info.hide_followers -> [] + user.info.hide_network -> [] true -> followers end @@ -621,7 +621,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do followers = cond do for_user && user.id == for_user.id -> followers - user.info.hide_followings -> [] + user.info.hide_network -> [] true -> followers end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index d5b7e68c7..d1b11d4f1 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -182,8 +182,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do end def render("card.json", %{rich_media: rich_media, page_url: page_url}) do - page_url = rich_media[:url] || page_url - page_url_data = URI.parse(page_url) + page_url_data = + if rich_media[:url] != nil do + URI.merge(URI.parse(page_url), URI.parse(rich_media[:url])) + else + page_url + end + + page_url = page_url_data |> to_string + + image_url = + URI.merge(page_url_data, URI.parse(rich_media[:image])) + |> to_string + site_name = rich_media[:site_name] || page_url_data.host %{ @@ -191,7 +202,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do provider_name: site_name, provider_url: page_url_data.scheme <> "://" <> page_url_data.host, url: page_url, - image: rich_media[:image] |> MediaProxy.url(), + image: image_url |> MediaProxy.url(), title: rich_media[:title], description: rich_media[:description], pleroma: %{ diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex index 07ca42a5f..b1c2dc7fa 100644 --- a/lib/pleroma/web/salmon/salmon.ex +++ b/lib/pleroma/web/salmon/salmon.ex @@ -162,30 +162,31 @@ defmodule Pleroma.Web.Salmon do |> Enum.filter(fn user -> user && !user.local end) end - # push an activity to remote accounts - # - def send_to_user(%{info: %{salmon: salmon}}, feed, poster), - do: send_to_user(salmon, feed, poster) + @doc "Pushes an activity to remote account." + def send_to_user(%{recipient: %{info: %{salmon: salmon}}} = params), + do: send_to_user(Map.put(params, :recipient, salmon)) - def send_to_user(url, feed, poster) when is_binary(url) do + def send_to_user(%{recipient: url, feed: feed, poster: poster} = params) when is_binary(url) do with {:ok, %{status: code}} when code in 200..299 <- poster.( url, feed, [{"Content-Type", "application/magic-envelope+xml"}] ) do - Instances.set_reachable(url) + if !Map.has_key?(params, :unreachable_since) || params[:unreachable_since], + do: Instances.set_reachable(url) + Logger.debug(fn -> "Pushed to #{url}, code #{code}" end) :ok else e -> - Instances.set_unreachable(url) + unless params[:unreachable_since], do: Instances.set_reachable(url) Logger.debug(fn -> "Pushing Salmon to #{url} failed, #{inspect(e)}" end) :error end end - def send_to_user(_, _, _), do: :noop + def send_to_user(_), do: :noop @supported_activities [ "Create", @@ -218,13 +219,20 @@ defmodule Pleroma.Web.Salmon do remote_users = remote_users(activity) salmon_urls = Enum.map(remote_users, & &1.info.salmon) - reachable_salmon_urls = Instances.filter_reachable(salmon_urls) + reachable_urls_metadata = Instances.filter_reachable(salmon_urls) + reachable_urls = Map.keys(reachable_urls_metadata) remote_users - |> Enum.filter(&(&1.info.salmon in reachable_salmon_urls)) + |> Enum.filter(&(&1.info.salmon in reachable_urls)) |> Enum.each(fn remote_user -> Logger.debug(fn -> "Sending Salmon to #{remote_user.ap_id}" end) - Pleroma.Web.Federator.enqueue(:publish_single_salmon, {remote_user, feed, poster}) + + Pleroma.Web.Federator.enqueue(:publish_single_salmon, %{ + recipient: remote_user, + feed: feed, + poster: poster, + unreachable_since: reachable_urls_metadata[remote_user.info.salmon] + }) end) end end diff --git a/lib/pleroma/web/templates/layout/app.html.eex b/lib/pleroma/web/templates/layout/app.html.eex index 2e96c1509..8dd3284d6 100644 --- a/lib/pleroma/web/templates/layout/app.html.eex +++ b/lib/pleroma/web/templates/layout/app.html.eex @@ -1,7 +1,8 @@ <!DOCTYPE html> <html> <head> - <meta charset=utf-8 /> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1,minimal-ui" /> <title> <%= Application.get_env(:pleroma, :instance)[:name] %> </title> diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 5e3fe9352..3064d61ea 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -503,7 +503,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do followers = cond do for_user && user.id == for_user.id -> followers - user.info.hide_followers -> [] + user.info.hide_network -> [] true -> followers end @@ -523,7 +523,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do friends = cond do for_user && user.id == for_user.id -> friends - user.info.hide_followings -> [] + user.info.hide_network -> [] true -> friends end @@ -618,7 +618,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do defp build_info_cng(user, params) do info_params = - ["no_rich_text", "locked", "hide_followers", "hide_followings"] + ["no_rich_text", "locked", "hide_network"] |> Enum.reduce(%{}, fn key, res -> if value = params[key] do Map.put(res, key, value == "true") diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index cd7c4349c..15682db8f 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -108,8 +108,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do "locked" => user.info.locked, "default_scope" => user.info.default_scope, "no_rich_text" => user.info.no_rich_text, - "hide_followers" => user.info.hide_followers, - "hide_followings" => user.info.hide_followings, + "hide_network" => user.info.hide_network, "fields" => fields, # Pleroma extension diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex index 8f7d53b03..90ba79962 100644 --- a/lib/pleroma/web/websub/websub.ex +++ b/lib/pleroma/web/websub/websub.ex @@ -70,7 +70,8 @@ defmodule Pleroma.Web.Websub do subscriptions = Repo.all(query) callbacks = Enum.map(subscriptions, & &1.callback) - reachable_callbacks = Instances.filter_reachable(callbacks) + reachable_callbacks_metadata = Instances.filter_reachable(callbacks) + reachable_callbacks = Map.keys(reachable_callbacks_metadata) subscriptions |> Enum.filter(&(&1.callback in reachable_callbacks)) @@ -79,7 +80,8 @@ defmodule Pleroma.Web.Websub do xml: response, topic: topic, callback: sub.callback, - secret: sub.secret + secret: sub.secret, + unreachable_since: reachable_callbacks_metadata[sub.callback] } Pleroma.Web.Federator.enqueue(:publish_single_websub, data) @@ -268,7 +270,7 @@ defmodule Pleroma.Web.Websub do end) end - def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret}) do + def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret} = params) do signature = sign(secret || "", xml) Logger.info(fn -> "Pushing #{topic} to #{callback}" end) @@ -281,12 +283,14 @@ defmodule Pleroma.Web.Websub do {"X-Hub-Signature", "sha1=#{signature}"} ] ) do - Instances.set_reachable(callback) + if !Map.has_key?(params, :unreachable_since) || params[:unreachable_since], + do: Instances.set_reachable(callback) + Logger.info(fn -> "Pushed to #{callback}, code #{code}" end) {:ok, code} else {_post_result, response} -> - Instances.set_unreachable(callback) + unless params[:unreachable_since], do: Instances.set_reachable(callback) Logger.debug(fn -> "Couldn't push to #{callback}, #{inspect(response)}" end) {:error, response} end |