X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Fweb_finger%2Fweb_finger.ex;h=5ea5ae48e809fe21b3770b05c5e7f1a389d552fe;hb=6c8d15da110e86f799052c82df8b7b2404f8f722;hp=6e5fc140185dcbfa122c5c701e6232b887e36534;hpb=7831b38705654d77bddd14b0f4542b9ae7e9e82d;p=akkoma diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 6e5fc1401..5ea5ae48e 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -1,9 +1,16 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.WebFinger do @httpoison Application.get_env(:pleroma, :httpoison) - alias Pleroma.{User, XmlBuilder} + alias Pleroma.User + alias Pleroma.XmlBuilder alias Pleroma.Web - alias Pleroma.Web.{XML, Salmon, OStatus} + alias Pleroma.Web.XML + alias Pleroma.Web.Salmon + alias Pleroma.Web.OStatus require Jason require Logger @@ -25,35 +32,17 @@ defmodule Pleroma.Web.WebFinger do |> XmlBuilder.to_doc() end - def webfinger(resource, "JSON") do - host = Pleroma.Web.Endpoint.host() - regex = ~r/(acct:)?(?\w+)@#{host}/ - - with %{"username" => username} <- Regex.named_captures(regex, resource) do - user = User.get_by_nickname(username) - {:ok, represent_user(user, "JSON")} - else - _e -> - with user when not is_nil(user) <- User.get_cached_by_ap_id(resource) do - {:ok, represent_user(user, "JSON")} - else - _e -> - {:error, "Couldn't find user"} - end - end - end - - def webfinger(resource, "XML") do + def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do host = Pleroma.Web.Endpoint.host() regex = ~r/(acct:)?(?\w+)@#{host}/ - with %{"username" => username} <- Regex.named_captures(regex, resource) do - user = User.get_by_nickname(username) - {:ok, represent_user(user, "XML")} + with %{"username" => username} <- Regex.named_captures(regex, resource), + %User{} = user <- User.get_by_nickname(username) do + {:ok, represent_user(user, fmt)} else _e -> - with user when not is_nil(user) <- User.get_cached_by_ap_id(resource) do - {:ok, represent_user(user, "XML")} + with %User{} = user <- User.get_cached_by_ap_id(resource) do + {:ok, represent_user(user, fmt)} else _e -> {:error, "Couldn't find user"} @@ -63,7 +52,7 @@ defmodule Pleroma.Web.WebFinger do def represent_user(user, "JSON") do {:ok, user} = ensure_keys_present(user) - {:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"]) + {:ok, _private, public} = Salmon.keys_from_pem(user.info.keys) magic_key = Salmon.encode_key(public) %{ @@ -101,7 +90,7 @@ defmodule Pleroma.Web.WebFinger do def represent_user(user, "XML") do {:ok, user} = ensure_keys_present(user) - {:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"]) + {:ok, _private, public} = Salmon.keys_from_pem(user.info.keys) magic_key = Salmon.encode_key(public) { @@ -131,54 +120,69 @@ defmodule Pleroma.Web.WebFinger do # This seems a better fit in Salmon def ensure_keys_present(user) do - info = user.info || %{} + info = user.info - if info["keys"] do + if info.keys do {:ok, user} else {:ok, pem} = Salmon.generate_rsa_pem() - info = Map.put(info, "keys", pem) - Ecto.Changeset.change(user, info: info) - |> User.update_and_set_cache() + info_cng = + info + |> Pleroma.User.Info.set_keys(pem) + + cng = + Ecto.Changeset.change(user) + |> Ecto.Changeset.put_embed(:info, info_cng) + + User.update_and_set_cache(cng) 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 @@ -214,7 +218,7 @@ defmodule Pleroma.Web.WebFinger do end def get_template_from_xml(body) do - xpath = "//Link[@rel='lrdd' and @type='application/xrd+xml']/@template" + xpath = "//Link[@rel='lrdd']/@template" with doc when doc != :error <- XML.parse_document(body), template when template != nil <- XML.string_from_xpath(xpath, doc) do @@ -223,8 +227,8 @@ defmodule Pleroma.Web.WebFinger do end def find_lrdd_template(domain) do - with {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- - @httpoison.get("http://#{domain}/.well-known/host-meta", [], follow_redirect: true) do + with {:ok, %{status: status, body: body}} when status in 200..299 <- + @httpoison.get("http://#{domain}/.well-known/host-meta", []) do get_template_from_xml(body) else _ -> @@ -253,23 +257,25 @@ 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 <- @httpoison.get( address, - [Accept: "application/xrd+xml,application/jrd+json"], - follow_redirect: true + Accept: "application/xrd+xml,application/jrd+json" ), - {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- response do + {:ok, %{status: status, body: body}} when status in 200..299 <- response do doc = XML.parse_document(body) 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 ->