diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/activity.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub.ex | 14 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub_controller.ex | 12 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/mrf/reject_non_public.ex | 29 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/transmogrifier.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/common_api/utils.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 28 | ||||
-rw-r--r-- | lib/pleroma/web/oauth/oauth_controller.ex | 46 | ||||
-rw-r--r-- | lib/pleroma/web/ostatus/ostatus_controller.ex | 112 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/controllers/util_controller.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api_controller.ex | 23 | ||||
-rw-r--r-- | lib/pleroma/web/web_finger/web_finger.ex | 82 | ||||
-rw-r--r-- | lib/pleroma/web/xml/xml.ex | 4 |
15 files changed, 269 insertions, 111 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index c7502981e..dd6805125 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -72,8 +72,10 @@ defmodule Pleroma.Activity do ) end - def get_create_activity_by_object_ap_id(ap_id) do + def get_create_activity_by_object_ap_id(ap_id) when is_binary(ap_id) do create_activity_by_object_id_query([ap_id]) |> Repo.one() end + + def get_create_activity_by_object_ap_id(_), do: nil end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index aecf96c36..00cac153d 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -174,7 +174,7 @@ defmodule Pleroma.User do should_direct_follow = cond do # if the account is locked, don't pre-create the relationship - user_info["locked"] == true -> + user_info[:locked] == true -> false # if the users are blocking each other, we shouldn't even be here, but check for it anyway @@ -193,7 +193,7 @@ defmodule Pleroma.User do if should_direct_follow do follow(follower, followed) else - follower + {:ok, follower} end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index a5e42d9d0..43e96fe37 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -564,6 +564,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end end + @quarantined_instances Keyword.get(@instance, :quarantined_instances, []) + + def should_federate?(inbox, public) do + if public do + true + else + inbox_info = URI.parse(inbox) + inbox_info.host not in @quarantined_instances + end + end + def publish(actor, activity) do followers = if actor.follower_address in activity.recipients do @@ -573,6 +584,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do [] end + public = is_public?(activity) + remote_inboxes = (Pleroma.Web.Salmon.remote_users(activity) ++ followers) |> Enum.filter(fn user -> User.ap_enabled?(user) end) @@ -580,6 +593,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do (data["endpoints"] && data["endpoints"]["sharedInbox"]) || data["inbox"] end) |> Enum.uniq() + |> Enum.filter(fn inbox -> should_federate?(inbox, public) end) {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) json = Jason.encode!(data) diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index a6a9b99ef..d337532d0 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -15,6 +15,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do conn |> put_resp_header("content-type", "application/activity+json") |> json(UserView.render("user.json", %{user: user})) + else + nil -> {:error, :not_found} end end @@ -27,9 +29,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do |> json(ObjectView.render("object.json", %{object: object})) else {:public?, false} -> - conn - |> put_status(404) - |> json("Not found") + {:error, :not_found} end end @@ -107,6 +107,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do json(conn, "ok") end + def errors(conn, {:error, :not_found}) do + conn + |> put_status(404) + |> json("Not found") + end + def errors(conn, _e) do conn |> put_status(500) diff --git a/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex new file mode 100644 index 000000000..879cbe6de --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/reject_non_public.ex @@ -0,0 +1,29 @@ +defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublic do + alias Pleroma.User + @behaviour Pleroma.Web.ActivityPub.MRF + + @impl true + def filter(object) do + if object["type"] == "Create" do + user = User.get_cached_by_ap_id(object["actor"]) + public = "https://www.w3.org/ns/activitystreams#Public" + + # Determine visibility + visibility = + cond do + public in object["to"] -> "public" + public in object["cc"] -> "unlisted" + user.follower_address in object["to"] -> "followers" + true -> "direct" + end + + case visibility do + "public" -> {:ok, object} + "unlisted" -> {:ok, object} + _ -> {:reject, nil} + end + else + {:ok, object} + end + end +end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 3c9377be9..75ba36729 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -252,11 +252,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do {:ok, new_user_data} = ActivityPub.user_data_from_user_object(object) banner = new_user_data[:info]["banner"] + locked = new_user_data[:info]["locked"] update_data = new_user_data |> Map.take([:name, :bio, :avatar]) - |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner})) + |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner, "locked" => locked})) actor |> User.upgrade_changeset(update_data) diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 9c9951371..30089f553 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -9,11 +9,12 @@ defmodule Pleroma.Web.CommonAPI.Utils do def get_by_id_or_ap_id(id) do activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id) - if activity.data["type"] == "Create" do - activity - else - Activity.get_create_activity_by_object_ap_id(activity.data["object"]) - end + activity && + if activity.data["type"] == "Create" do + activity + else + Activity.get_create_activity_by_object_ap_id(activity.data["object"]) + end end def get_replied_to_activity(id) when not is_nil(id) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 12f9b5f7c..0f7d4bb6d 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -10,6 +10,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do import Ecto.Query require Logger + action_fallback(:errors) + def create_app(conn, params) do with cs <- App.register_changeset(%App{}, params) |> IO.inspect(), {:ok, app} <- Repo.insert(cs) |> IO.inspect() do @@ -134,6 +136,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do %{ "shortcode" => shortcode, "static_url" => url, + "visible_in_picker" => true, "url" => url } end) @@ -244,7 +247,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end - def dm_timeline(%{assigns: %{user: user}} = conn, params) do + def dm_timeline(%{assigns: %{user: user}} = conn, _params) do query = ActivityPub.fetch_activities_query([user.ap_id], %{"type" => "Create", visibility: "direct"}) @@ -297,6 +300,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def post_status(conn, %{"status" => "", "media_ids" => media_ids} = params) + when length(media_ids) > 0 do + params = + params + |> Map.put("status", ".") + + post_status(conn, params) + end + def post_status(%{assigns: %{user: user}} = conn, %{"status" => _} = params) do params = params @@ -327,27 +339,27 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do - with {:ok, announce, _activity} = CommonAPI.repeat(ap_id_or_id, user) do + with {:ok, announce, _activity} <- CommonAPI.repeat(ap_id_or_id, user) do render(conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity}) end end def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do - with {:ok, _, _, %{data: %{"id" => id}}} = CommonAPI.unrepeat(ap_id_or_id, user), + with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) end end def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do - with {:ok, _fav, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user), + with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) end end def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do - with {:ok, _, _, %{data: %{"id" => id}}} = CommonAPI.unfavorite(ap_id_or_id, user), + with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) end @@ -933,4 +945,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do nil end end + + def errors(conn, _) do + conn + |> put_status(500) + |> json("Something went wrong") + end end diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 11dc1806f..3dd87d0ab 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -56,12 +56,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do # TODO # - proper scope handling def token_exchange(conn, %{"grant_type" => "authorization_code"} = params) do - with %App{} = app <- - Repo.get_by( - App, - client_id: params["client_id"], - client_secret: params["client_secret"] - ), + with %App{} = app <- get_app_from_request(conn, params), fixed_token = fix_padding(params["code"]), %Authorization{} = auth <- Repo.get_by(Authorization, token: fixed_token, app_id: app.id), @@ -76,7 +71,9 @@ defmodule Pleroma.Web.OAuth.OAuthController do json(conn, response) else - _error -> json(conn, %{error: "Invalid credentials"}) + _error -> + put_status(conn, 400) + |> json(%{error: "Invalid credentials"}) end end @@ -86,12 +83,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do conn, %{"grant_type" => "password", "name" => name, "password" => password} = params ) do - with %App{} = app <- - Repo.get_by( - App, - client_id: params["client_id"], - client_secret: params["client_secret"] - ), + with %App{} = app <- get_app_from_request(conn, params), %User{} = user <- User.get_cached_by_nickname(name), true <- Pbkdf2.checkpw(password, user.password_hash), {:ok, auth} <- Authorization.create_authorization(app, user), @@ -106,7 +98,9 @@ defmodule Pleroma.Web.OAuth.OAuthController do json(conn, response) else - _error -> json(conn, %{error: "Invalid credentials"}) + _error -> + put_status(conn, 400) + |> json(%{error: "Invalid credentials"}) end end @@ -115,4 +109,28 @@ defmodule Pleroma.Web.OAuth.OAuthController do |> Base.url_decode64!(padding: false) |> Base.url_encode64() end + + defp get_app_from_request(conn, params) do + # Per RFC 6749, HTTP Basic is preferred to body params + {client_id, client_secret} = + with ["Basic " <> encoded] <- get_req_header(conn, "authorization"), + {:ok, decoded} <- Base.decode64(encoded), + [id, secret] <- + String.split(decoded, ":") + |> Enum.map(fn s -> URI.decode_www_form(s) end) do + {id, secret} + else + _ -> {params["client_id"], params["client_secret"]} + end + + if client_id && client_secret do + Repo.get_by( + App, + client_id: client_id, + client_secret: client_secret + ) + else + nil + end + end end diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index 53278431e..2f72fdb16 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -9,36 +9,47 @@ defmodule Pleroma.Web.OStatus.OStatusController do alias Pleroma.Web.ActivityPub.ActivityPubController alias Pleroma.Web.ActivityPub.ActivityPub - def feed_redirect(conn, %{"nickname" => nickname} = params) do - user = User.get_cached_by_nickname(nickname) + action_fallback(:errors) + def feed_redirect(conn, %{"nickname" => nickname}) do case get_format(conn) do - "html" -> Fallback.RedirectController.redirector(conn, nil) - "activity+json" -> ActivityPubController.user(conn, params) - _ -> redirect(conn, external: OStatus.feed_path(user)) + "html" -> + Fallback.RedirectController.redirector(conn, nil) + + "activity+json" -> + ActivityPubController.call(conn, :user) + + _ -> + with %User{} = user <- User.get_cached_by_nickname(nickname) do + redirect(conn, external: OStatus.feed_path(user)) + else + nil -> {:error, :not_found} + end end end def feed(conn, %{"nickname" => nickname} = params) do - user = User.get_cached_by_nickname(nickname) - - query_params = - Map.take(params, ["max_id"]) - |> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id}) - - activities = - ActivityPub.fetch_public_activities(query_params) - |> Enum.reverse() - - response = - user - |> FeedRepresenter.to_simple_form(activities, [user]) - |> :xmerl.export_simple(:xmerl_xml) - |> to_string - - conn - |> put_resp_content_type("application/atom+xml") - |> send_resp(200, response) + with %User{} = user <- User.get_cached_by_nickname(nickname) do + query_params = + Map.take(params, ["max_id"]) + |> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id}) + + activities = + ActivityPub.fetch_public_activities(query_params) + |> Enum.reverse() + + response = + user + |> FeedRepresenter.to_simple_form(activities, [user]) + |> :xmerl.export_simple(:xmerl_xml) + |> to_string + + conn + |> put_resp_content_type("application/atom+xml") + |> send_resp(200, response) + else + nil -> {:error, :not_found} + end end defp decode_or_retry(body) do @@ -68,12 +79,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do |> send_resp(200, "") end - def object(conn, %{"uuid" => uuid} = params) do + def object(conn, %{"uuid" => uuid}) do if get_format(conn) == "activity+json" do - ActivityPubController.object(conn, params) + ActivityPubController.call(conn, :object) else with id <- o_status_url(conn, :object, uuid), - %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id), + {_, %Activity{} = activity} <- + {:activity, Activity.get_create_activity_by_object_ap_id(id)}, {_, true} <- {:public?, ActivityPub.is_public?(activity)}, %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do case get_format(conn) do @@ -82,16 +94,20 @@ defmodule Pleroma.Web.OStatus.OStatusController do end else {:public?, false} -> - conn - |> put_status(404) - |> json("Not found") + {:error, :not_found} + + {:activity, nil} -> + {:error, :not_found} + + e -> + e end end end def activity(conn, %{"uuid" => uuid}) do with id <- o_status_url(conn, :activity, uuid), - %Activity{} = activity <- Activity.get_by_ap_id(id), + {_, %Activity{} = activity} <- {:activity, Activity.get_by_ap_id(id)}, {_, true} <- {:public?, ActivityPub.is_public?(activity)}, %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do case get_format(conn) do @@ -100,14 +116,18 @@ defmodule Pleroma.Web.OStatus.OStatusController do end else {:public?, false} -> - conn - |> put_status(404) - |> json("Not found") + {:error, :not_found} + + {:activity, nil} -> + {:error, :not_found} + + e -> + e end end def notice(conn, %{"id" => id}) do - with %Activity{} = activity <- Repo.get(Activity, id), + with {_, %Activity{} = activity} <- {:activity, Repo.get(Activity, id)}, {_, true} <- {:public?, ActivityPub.is_public?(activity)}, %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do case get_format(conn) do @@ -121,9 +141,13 @@ defmodule Pleroma.Web.OStatus.OStatusController do end else {:public?, false} -> - conn - |> put_status(404) - |> json("Not found") + {:error, :not_found} + + {:activity, nil} -> + {:error, :not_found} + + e -> + e end end @@ -139,4 +163,16 @@ defmodule Pleroma.Web.OStatus.OStatusController do |> put_resp_content_type("application/atom+xml") |> send_resp(200, response) end + + def errors(conn, {:error, :not_found}) do + conn + |> put_status(404) + |> text("Not found") + end + + def errors(conn, _) do + conn + |> put_status(500) + |> text("Something went wrong") + end end diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index cc5146566..7a0c37ce9 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -189,7 +189,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do {:ok, follower} <- User.follow(follower, followed) do ActivityPub.follow(follower, followed) else - _e -> Logger.debug("follow_import: following #{account} failed") + err -> Logger.debug("follow_import: following #{account} failed with #{inspect(err)}") end end) end) diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 331efa90b..ccc6fe8e7 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -64,7 +64,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end def repeat(%User{} = user, ap_id_or_id) do - with {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(ap_id_or_id, user), + with {:ok, _announce, %{data: %{"id" => id}}} <- CommonAPI.repeat(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do {:ok, activity} end @@ -77,14 +77,14 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end def fav(%User{} = user, ap_id_or_id) do - with {:ok, _fav, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user), + with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do {:ok, activity} end end def unfav(%User{} = user, ap_id_or_id) do - with {:ok, _unfav, _fav, %{data: %{"id" => id}}} = CommonAPI.unfavorite(ap_id_or_id, user), + with {:ok, _unfav, _fav, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do {:ok, activity} end diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 320f2fcf4..d53dd0c44 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -8,6 +8,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do require Logger + action_fallback(:errors) + def verify_credentials(%{assigns: %{user: user}} = conn, _params) do token = Phoenix.Token.sign(conn, "user socket", user.id) render(conn, UserView, "show.json", %{user: user, token: token}) @@ -218,19 +220,22 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {:ok, activity} <- TwitterAPI.fav(user, id) do + with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, + {:ok, activity} <- TwitterAPI.fav(user, id) do render(conn, ActivityView, "activity.json", %{activity: activity, for: user}) end end def unfavorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {:ok, activity} <- TwitterAPI.unfav(user, id) do + with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, + {:ok, activity} <- TwitterAPI.unfav(user, id) do render(conn, ActivityView, "activity.json", %{activity: activity, for: user}) end end def retweet(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with {:ok, activity} <- TwitterAPI.repeat(user, id) do + with {_, {:ok, id}} <- {:param_cast, Ecto.Type.cast(:integer, id)}, + {:ok, activity} <- TwitterAPI.repeat(user, id) do render(conn, ActivityView, "activity.json", %{activity: activity, for: user}) end end @@ -389,4 +394,16 @@ defmodule Pleroma.Web.TwitterAPI.Controller do defp error_json(conn, error_message) do %{"error" => error_message, "request" => conn.request_path} |> Jason.encode!() end + + def errors(conn, {:param_cast, _}) do + conn + |> put_status(400) + |> json("Invalid parameters") + end + + def errors(conn, _) do + conn + |> put_status(500) + |> json("Something went wrong") + end end diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 9c6f1cb68..e7ee810f9 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -144,41 +144,50 @@ defmodule Pleroma.Web.WebFinger do end end - defp webfinger_from_xml(doc) do - magic_key = XML.string_from_xpath(~s{//Link[@rel="magic-public-key"]/@href}, doc) + defp get_magic_key(magic_key) do "data:application/magic-public-key," <> magic_key = magic_key + {:ok, magic_key} + rescue + MatchError -> {:error, "Missing magic key data."} + end - topic = - XML.string_from_xpath( - ~s{//Link[@rel="http://schemas.google.com/g/2010#updates-from"]/@href}, - doc - ) - - subject = XML.string_from_xpath("//Subject", doc) - salmon = XML.string_from_xpath(~s{//Link[@rel="salmon"]/@href}, doc) - - subscribe_address = - XML.string_from_xpath( - ~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}, - doc - ) - - ap_id = - XML.string_from_xpath( - ~s{//Link[@rel="self" and @type="application/activity+json"]/@href}, - doc - ) - - data = %{ - "magic_key" => magic_key, - "topic" => topic, - "subject" => subject, - "salmon" => salmon, - "subscribe_address" => subscribe_address, - "ap_id" => ap_id - } + defp webfinger_from_xml(doc) do + with magic_key <- XML.string_from_xpath(~s{//Link[@rel="magic-public-key"]/@href}, doc), + {:ok, magic_key} <- get_magic_key(magic_key), + topic <- + XML.string_from_xpath( + ~s{//Link[@rel="http://schemas.google.com/g/2010#updates-from"]/@href}, + doc + ), + subject <- XML.string_from_xpath("//Subject", doc), + salmon <- XML.string_from_xpath(~s{//Link[@rel="salmon"]/@href}, doc), + subscribe_address <- + XML.string_from_xpath( + ~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}, + doc + ), + ap_id <- + XML.string_from_xpath( + ~s{//Link[@rel="self" and @type="application/activity+json"]/@href}, + doc + ) do + data = %{ + "magic_key" => magic_key, + "topic" => topic, + "subject" => subject, + "salmon" => salmon, + "subscribe_address" => subscribe_address, + "ap_id" => ap_id + } - {:ok, data} + {:ok, data} + else + {:error, e} -> + {:error, e} + + e -> + {:error, e} + end end defp webfinger_from_json(doc) do @@ -253,7 +262,7 @@ defmodule Pleroma.Web.WebFinger do String.replace(template, "{uri}", URI.encode(account)) _ -> - "http://#{domain}/.well-known/webfinger?resource=acct:#{account}" + "https://#{domain}/.well-known/webfinger?resource=acct:#{account}" end with response <- @@ -268,8 +277,11 @@ defmodule Pleroma.Web.WebFinger do if doc != :error do webfinger_from_xml(doc) else - {:ok, doc} = Jason.decode(body) - webfinger_from_json(doc) + with {:ok, doc} <- Jason.decode(body) do + webfinger_from_json(doc) + else + {:error, e} -> e + end end else e -> diff --git a/lib/pleroma/web/xml/xml.ex b/lib/pleroma/web/xml/xml.ex index 36430a3fa..da3f68ecb 100644 --- a/lib/pleroma/web/xml/xml.ex +++ b/lib/pleroma/web/xml/xml.ex @@ -32,6 +32,10 @@ defmodule Pleroma.Web.XML do :exit, _error -> Logger.debug("Couldn't parse XML: #{inspect(text)}") :error + rescue + e -> + Logger.debug("Couldn't parse XML: #{inspect(text)}") + :error end end end |