Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85710824
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
index 7ceca042b..f8f4d5e42 100644
--- a/lib/pleroma/web/web_finger/web_finger.ex
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -1,103 +1,107 @@
defmodule Pleroma.Web.WebFinger do
alias Pleroma.XmlBuilder
alias Pleroma.{Repo, User}
alias Pleroma.Web.{XML, Salmon, OStatus}
require Logger
def host_meta() do
base_url = Pleroma.Web.base_url
{
:XRD, %{ xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0" },
{
:Link, %{ rel: "lrdd", type: "application/xrd+xml", template: "#{base_url}/.well-known/webfinger?resource={uri}" }
}
}
|> XmlBuilder.to_doc
end
def webfinger(resource) do
host = Pleroma.Web.host
regex = ~r/(acct:)?(?<username>\w+)@#{host}/
- case Regex.named_captures(regex, resource) do
- %{"username" => username} ->
- user = User.get_by_nickname(username)
+ with %{"username" => username} <- Regex.named_captures(regex, resource) do
+ user = User.get_by_nickname(username)
+ {:ok, represent_user(user)}
+ else _e ->
+ with user when not is_nil(user) <- User.get_cached_by_ap_id(resource) do
{:ok, represent_user(user)}
- _ -> nil
+ else _e ->
+ {:error, "Couldn't find user"}
+ end
end
end
def represent_user(user) do
{:ok, user} = ensure_keys_present(user)
{:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"])
magic_key = Salmon.encode_key(public)
{
:XRD, %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
[
{:Subject, "acct:#{user.nickname}@#{Pleroma.Web.host}"},
{:Alias, user.ap_id},
{:Link, %{rel: "http://schemas.google.com/g/2010#updates-from", type: "application/atom+xml", href: OStatus.feed_path(user)}},
{:Link, %{rel: "salmon", href: OStatus.salmon_path(user)}},
{:Link, %{rel: "magic-public-key", href: "data:application/magic-public-key,#{magic_key}"}}
]
}
|> XmlBuilder.to_doc
end
def ensure_keys_present(user) do
info = user.info || %{}
if info["keys"] do
{:ok, user}
else
{:ok, pem} = Salmon.generate_rsa_pem
info = Map.put(info, "keys", pem)
Repo.update(Ecto.Changeset.change(user, info: info))
end
end
# FIXME: Make this call the host-meta to find the actual address.
defp webfinger_address(domain) do
"//#{domain}/.well-known/webfinger"
end
defp webfinger_from_xml(doc) do
magic_key = XML.string_from_xpath(~s{//Link[@rel="magic-public-key"]/@href}, doc)
"data:application/magic-public-key," <> 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)
data = %{
magic_key: magic_key,
topic: topic,
subject: subject,
salmon: salmon
}
{:ok, data}
end
def finger(account, getter \\ &HTTPoison.get/3) do
domain = with [_name, domain] <- String.split(account, "@") do
domain
else _e ->
URI.parse(account).host
end
address = webfinger_address(domain)
# try https first
response = with {:ok, result} <- getter.("https:" <> address, ["Accept": "application/xrd+xml"], [params: [resource: account]]) do
{:ok, result}
else _ ->
getter.("http:" <> address, ["Accept": "application/xrd+xml"], [params: [resource: account]])
end
with {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- response,
doc <- XML.parse_document(body),
{:ok, data} <- webfinger_from_xml(doc) do
{:ok, data}
else
e ->
Logger.debug("Couldn't finger #{account}.")
Logger.debug(inspect(e))
{:error, e}
end
end
end
diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs
index 303abe529..b48fdd0aa 100644
--- a/test/web/web_finger/web_finger_test.exs
+++ b/test/web/web_finger/web_finger_test.exs
@@ -1,45 +1,61 @@
defmodule Pleroma.Web.WebFingerTest do
use Pleroma.DataCase
alias Pleroma.Web.WebFinger
import Pleroma.Factory
describe "host meta" do
test "returns a link to the xml lrdd" do
host_info = WebFinger.host_meta()
assert String.contains?(host_info, Pleroma.Web.base_url)
end
end
+ describe "incoming webfinger request" do
+ test "works for fqns" do
+ user = insert(:user)
+
+ {:ok, result} = WebFinger.webfinger("#{user.nickname}@#{Pleroma.Web.host}")
+ assert is_binary(result)
+ end
+
+ test "works for ap_ids" do
+ user = insert(:user)
+
+ {:ok, result} = WebFinger.webfinger(user.ap_id)
+ assert is_binary(result)
+ end
+ end
+
describe "fingering" do
test "returns the info for a user" do
user = "shp@social.heldscal.la"
getter = fn(_url, _headers, [params: [resource: ^user]]) ->
{:ok, %{status_code: 200, body: File.read!("test/fixtures/webfinger.xml")}}
end
{:ok, data} = WebFinger.finger(user, getter)
assert data.magic_key == "RSA.wQ3i9UA0qmAxZ0WTIp4a-waZn_17Ez1pEEmqmqoooRsG1_BvpmOvLN0G2tEcWWxl2KOtdQMCiPptmQObeZeuj48mdsDZ4ArQinexY2hCCTcbV8Xpswpkb8K05RcKipdg07pnI7tAgQ0VWSZDImncL6YUGlG5YN8b5TjGOwk2VG8=.AQAB"
assert data.topic == "https://social.heldscal.la/api/statuses/user_timeline/29191.atom"
assert data.subject == "acct:shp@social.heldscal.la"
assert data.salmon == "https://social.heldscal.la/main/salmon/user/29191"
end
end
describe "ensure_keys_present" do
test "it creates keys for a user and stores them in info" do
user = insert(:user)
refute is_binary(user.info["keys"])
{:ok, user} = WebFinger.ensure_keys_present(user)
assert is_binary(user.info["keys"])
end
test "it doesn't create keys if there already are some" do
user = insert(:user, %{info: %{"keys" => "xxx"}})
{:ok, user} = WebFinger.ensure_keys_present(user)
assert user.info["keys"] == "xxx"
end
end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Sep 19, 2:26 AM (17 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1768678
Default Alt Text
(6 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment