diff options
author | Haelwenn <contact+git.pleroma.social@hacktivis.me> | 2022-11-03 15:03:50 +0000 |
---|---|---|
committer | Haelwenn <contact+git.pleroma.social@hacktivis.me> | 2022-11-03 15:03:50 +0000 |
commit | 127e7b8ff9e5e7e1d26b6f7d80985f8144644ee5 (patch) | |
tree | 8cb3efaeb2cbfebcddc79bcc2cdef2c480ad6453 /lib | |
parent | da0ef154a6ea87abbe81a094c444546a3e62c723 (diff) | |
parent | 8407e26b0c1ec315fe8864948c78657f29f370c7 (diff) | |
download | pleroma-127e7b8ff9e5e7e1d26b6f7d80985f8144644ee5.tar.gz pleroma-127e7b8ff9e5e7e1d26b6f7d80985f8144644ee5.zip |
Merge branch 'feature/1469-webfinger-expanding' into 'develop'
Feature/1469 webfinger expanding
Closes #1469 and #2517
See merge request pleroma/pleroma!3361
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/http.ex | 9 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 57 | ||||
-rw-r--r-- | lib/pleroma/web/web_finger.ex | 47 |
3 files changed, 65 insertions, 48 deletions
diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex index 2e82ceff2..d41061538 100644 --- a/lib/pleroma/http.ex +++ b/lib/pleroma/http.ex @@ -106,5 +106,12 @@ defmodule Pleroma.HTTP do [Tesla.Middleware.FollowRedirects, Pleroma.Tesla.Middleware.ConnectionPool] end - defp adapter_middlewares(_), do: [] + defp adapter_middlewares(_) do + if Pleroma.Config.get(:env) == :test do + # Emulate redirects in test env, which are handled by adapters in other environments + [Tesla.Middleware.FollowRedirects] + else + [] + end + end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index a5d7036d9..5099caef7 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1482,7 +1482,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image() defp normalize_image(_), do: nil - defp object_to_user_data(data) do + defp object_to_user_data(data, additional) do fields = data |> Map.get("attachment", []) @@ -1514,15 +1514,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do public_key = if is_map(data["publicKey"]) && is_binary(data["publicKey"]["publicKeyPem"]) do data["publicKey"]["publicKeyPem"] - else - nil end shared_inbox = if is_map(data["endpoints"]) && is_binary(data["endpoints"]["sharedInbox"]) do data["endpoints"]["sharedInbox"] - else - nil end birthday = @@ -1531,13 +1527,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do {:ok, date} -> date {:error, _} -> nil end - else - nil end show_birthday = !!birthday - user_data = %{ + # if WebFinger request was already done, we probably have acct, otherwise + # we request WebFinger here + nickname = additional[:nickname_from_acct] || generate_nickname(data) + + %{ ap_id: data["id"], uri: get_actor_url(data["url"]), ap_enabled: true, @@ -1559,23 +1557,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do inbox: data["inbox"], shared_inbox: shared_inbox, accepts_chat_messages: accepts_chat_messages, - pinned_objects: pinned_objects, birthday: birthday, - show_birthday: show_birthday + show_birthday: show_birthday, + pinned_objects: pinned_objects, + nickname: nickname } + end - # nickname can be nil because of virtual actors - if data["preferredUsername"] do - Map.put( - user_data, - :nickname, - "#{data["preferredUsername"]}@#{URI.parse(data["id"]).host}" - ) + defp generate_nickname(%{"preferredUsername" => username} = data) when is_binary(username) do + generated = "#{username}@#{URI.parse(data["id"]).host}" + + if Config.get([WebFinger, :update_nickname_on_user_fetch]) do + case WebFinger.finger(generated) do + {:ok, %{"subject" => "acct:" <> acct}} -> acct + _ -> generated + end else - Map.put(user_data, :nickname, nil) + generated end end + # nickname can be nil because of virtual actors + defp generate_nickname(_), do: nil + def fetch_follow_information_for_user(user) do with {:ok, following_data} <- Fetcher.fetch_and_contain_remote_object_from_id(user.following_address), @@ -1647,17 +1651,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp collection_private(_data), do: {:ok, true} - def user_data_from_user_object(data) do + def user_data_from_user_object(data, additional \\ []) do with {:ok, data} <- MRF.filter(data) do - {:ok, object_to_user_data(data)} + {:ok, object_to_user_data(data, additional)} else e -> {:error, e} end end - def fetch_and_prepare_user_from_ap_id(ap_id) do + def fetch_and_prepare_user_from_ap_id(ap_id, additional \\ []) do with {:ok, data} <- Fetcher.fetch_and_contain_remote_object_from_id(ap_id), - {:ok, data} <- user_data_from_user_object(data) do + {:ok, data} <- user_data_from_user_object(data, additional) do {:ok, maybe_update_follow_information(data)} else # If this has been deleted, only log a debug and not an error @@ -1735,13 +1739,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end - def make_user_from_ap_id(ap_id) do + def make_user_from_ap_id(ap_id, additional \\ []) do user = User.get_cached_by_ap_id(ap_id) if user && !User.ap_enabled?(user) do Transmogrifier.upgrade_user_from_ap_id(ap_id) else - with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id) do + with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id, additional) do {:ok, _pid} = Task.start(fn -> pinned_fetch_task(data) end) if user do @@ -1761,8 +1765,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end def make_user_from_nickname(nickname) do - with {:ok, %{"ap_id" => ap_id}} when not is_nil(ap_id) <- WebFinger.finger(nickname) do - make_user_from_ap_id(ap_id) + with {:ok, %{"ap_id" => ap_id, "subject" => "acct:" <> acct}} when not is_nil(ap_id) <- + WebFinger.finger(nickname) do + make_user_from_ap_id(ap_id, nickname_from_acct: acct) else _e -> {:error, "No AP id in WebFinger"} end diff --git a/lib/pleroma/web/web_finger.ex b/lib/pleroma/web/web_finger.ex index 77ff40f46..f95dc2458 100644 --- a/lib/pleroma/web/web_finger.ex +++ b/lib/pleroma/web/web_finger.ex @@ -32,7 +32,13 @@ defmodule Pleroma.Web.WebFinger do def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do host = Pleroma.Web.Endpoint.host() - regex = ~r/(acct:)?(?<username>[a-z0-9A-Z_\.-]+)@#{host}/ + + regex = + if webfinger_domain = Pleroma.Config.get([__MODULE__, :domain]) do + ~r/(acct:)?(?<username>[a-z0-9A-Z_\.-]+)@(#{host}|#{webfinger_domain})/ + else + ~r/(acct:)?(?<username>[a-z0-9A-Z_\.-]+)@#{host}/ + end with %{"username" => username} <- Regex.named_captures(regex, resource), %User{} = user <- User.get_cached_by_nickname(username) do @@ -64,7 +70,7 @@ defmodule Pleroma.Web.WebFinger do def represent_user(user, "JSON") do %{ - "subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}", + "subject" => "acct:#{user.nickname}@#{domain()}", "aliases" => gather_aliases(user), "links" => gather_links(user) } @@ -84,12 +90,16 @@ defmodule Pleroma.Web.WebFinger do :XRD, %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"}, [ - {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"} + {:Subject, "acct:#{user.nickname}@#{domain()}"} ] ++ aliases ++ links } |> XmlBuilder.to_doc() end + defp domain do + Pleroma.Config.get([__MODULE__, :domain]) || Pleroma.Web.Endpoint.host() + end + defp webfinger_from_xml(body) do with {:ok, doc} <- XML.parse_document(body) do subject = XML.string_from_xpath("//Subject", doc) @@ -146,17 +156,15 @@ defmodule Pleroma.Web.WebFinger do end def find_lrdd_template(domain) do - with {:ok, %{status: status, body: body}} when status in 200..299 <- - HTTP.get("http://#{domain}/.well-known/host-meta") do + # WebFinger is restricted to HTTPS - https://tools.ietf.org/html/rfc7033#section-9.1 + meta_url = "https://#{domain}/.well-known/host-meta" + + with {:ok, %{status: status, body: body}} when status in 200..299 <- HTTP.get(meta_url) do get_template_from_xml(body) else - _ -> - with {:ok, %{body: body, status: status}} when status in 200..299 <- - HTTP.get("https://#{domain}/.well-known/host-meta") do - get_template_from_xml(body) - else - e -> {:error, "Can't find LRDD template: #{inspect(e)}"} - end + error -> + Logger.warn("Can't find LRDD template in #{inspect(meta_url)}: #{inspect(error)}") + {:error, :lrdd_not_found} end end @@ -170,7 +178,7 @@ defmodule Pleroma.Web.WebFinger do end end - defp get_address_from_domain(_, _), do: nil + defp get_address_from_domain(_, _), do: {:error, :webfinger_no_domain} @spec finger(String.t()) :: {:ok, map()} | {:error, any()} def finger(account) do @@ -187,13 +195,11 @@ defmodule Pleroma.Web.WebFinger do encoded_account = URI.encode("acct:#{account}") with address when is_binary(address) <- get_address_from_domain(domain, encoded_account), - response <- + {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <- HTTP.get( address, [{"accept", "application/xrd+xml,application/jrd+json"}] - ), - {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <- - response do + ) do case List.keyfind(headers, "content-type", 0) do {_, content_type} -> case Plug.Conn.Utils.media_type(content_type) do @@ -211,10 +217,9 @@ defmodule Pleroma.Web.WebFinger do {:error, {:content_type, nil}} end else - e -> - Logger.debug(fn -> "Couldn't finger #{account}" end) - Logger.debug(fn -> inspect(e) end) - {:error, e} + error -> + Logger.debug("Couldn't finger #{account}: #{inspect(error)}") + error end end end |