Merge pull request #63 from SuperTux88/rfc-7033
Implement RFC 7033 Webfinger
This commit is contained in:
commit
99a703ff5d
14 changed files with 343 additions and 97 deletions
|
|
@ -8,7 +8,8 @@ module DiasporaFederation
|
||||||
# example:
|
# example:
|
||||||
# <?xml version="1.0" encoding="UTF-8"?>
|
# <?xml version="1.0" encoding="UTF-8"?>
|
||||||
# <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
# <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||||
# <Link rel="lrdd" type="application/xrd+xml" template="https://server.example/webfinger?q={uri}"/>
|
# <Link rel="lrdd" type="application/xrd+xml"
|
||||||
|
# template="https://server.example/.well-known/webfinger.xml?resource={uri}"/>
|
||||||
# </XRD>
|
# </XRD>
|
||||||
#
|
#
|
||||||
# GET /.well-known/host-meta
|
# GET /.well-known/host-meta
|
||||||
|
|
@ -16,9 +17,47 @@ module DiasporaFederation
|
||||||
render xml: WebfingerController.host_meta_xml, content_type: "application/xrd+xml"
|
render xml: WebfingerController.host_meta_xml, content_type: "application/xrd+xml"
|
||||||
end
|
end
|
||||||
|
|
||||||
# @deprecated This is the pre RFC 7033 webfinger.
|
# Returns the webfinger as RFC 7033 JRD or XRD.
|
||||||
#
|
#
|
||||||
# example:
|
# JSON example:
|
||||||
|
# {
|
||||||
|
# "subject": "acct:alice@localhost:3000",
|
||||||
|
# "aliases": [
|
||||||
|
# "http://localhost:3000/people/c8e87290f6a20132963908fbffceb188"
|
||||||
|
# ],
|
||||||
|
# "links": [
|
||||||
|
# {
|
||||||
|
# "rel": "http://microformats.org/profile/hcard",
|
||||||
|
# "type": "text/html",
|
||||||
|
# "href": "http://localhost:3000/hcard/users/c8e87290f6a20132963908fbffceb188"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "rel": "http://joindiaspora.com/seed_location",
|
||||||
|
# "type": "text/html",
|
||||||
|
# "href": "http://localhost:3000/"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "rel": "http://webfinger.net/rel/profile-page",
|
||||||
|
# "type": "text/html",
|
||||||
|
# "href": "http://localhost:3000/u/alice"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "rel": "http://schemas.google.com/g/2010#updates-from",
|
||||||
|
# "type": "application/atom+xml",
|
||||||
|
# "href": "http://localhost:3000/public/alice.atom"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "rel": "salmon",
|
||||||
|
# "href": "http://localhost:3000/receive/users/c8e87290f6a20132963908fbffceb188"
|
||||||
|
# },
|
||||||
|
# {
|
||||||
|
# "rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
|
# "template": "http://localhost:3000/people?q={uri}"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# XML example:
|
||||||
# <?xml version="1.0" encoding="UTF-8"?>
|
# <?xml version="1.0" encoding="UTF-8"?>
|
||||||
# <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
# <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||||
# <Subject>acct:alice@localhost:3000</Subject>
|
# <Subject>acct:alice@localhost:3000</Subject>
|
||||||
|
|
@ -26,24 +65,32 @@ module DiasporaFederation
|
||||||
# <Link rel="http://microformats.org/profile/hcard" type="text/html"
|
# <Link rel="http://microformats.org/profile/hcard" type="text/html"
|
||||||
# href="http://localhost:3000/hcard/users/c8e87290f6a20132963908fbffceb188"/>
|
# href="http://localhost:3000/hcard/users/c8e87290f6a20132963908fbffceb188"/>
|
||||||
# <Link rel="http://joindiaspora.com/seed_location" type="text/html" href="http://localhost:3000/"/>
|
# <Link rel="http://joindiaspora.com/seed_location" type="text/html" href="http://localhost:3000/"/>
|
||||||
# <Link rel="http://joindiaspora.com/guid" type="text/html" href="c8e87290f6a20132963908fbffceb188"/>
|
|
||||||
# <Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="http://localhost:3000/u/alice"/>
|
# <Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="http://localhost:3000/u/alice"/>
|
||||||
# <Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml"
|
# <Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml"
|
||||||
# href="http://localhost:3000/public/alice.atom"/>
|
# href="http://localhost:3000/public/alice.atom"/>
|
||||||
# <Link rel="salmon" href="http://localhost:3000/receive/users/c8e87290f6a20132963908fbffceb188"/>
|
# <Link rel="salmon" href="http://localhost:3000/receive/users/c8e87290f6a20132963908fbffceb188"/>
|
||||||
# <Link rel="diaspora-public-key" type="RSA" href="LS0tLS1CRU......"/>
|
|
||||||
# </XRD>
|
# </XRD>
|
||||||
# GET /webfinger?q=<uri>
|
#
|
||||||
def legacy_webfinger
|
# GET /.well-known/webfinger?resource=<uri>
|
||||||
person_wf = find_person_webfinger(params[:q]) if params[:q]
|
def webfinger
|
||||||
|
person_wf = find_person_webfinger(params.require(:resource))
|
||||||
|
|
||||||
if person_wf.nil?
|
if person_wf.nil?
|
||||||
head :not_found
|
head :not_found
|
||||||
else
|
else
|
||||||
logger.info "webfinger profile request for: #{person_wf.acct_uri}"
|
logger.info "webfinger profile request for: #{person_wf.acct_uri}"
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.any(:jrd, :json, :html) do
|
||||||
|
headers["Access-Control-Allow-Origin"] = "*"
|
||||||
|
render json: JSON.pretty_generate(person_wf.to_json), content_type: "application/jrd+json"
|
||||||
|
end
|
||||||
|
format.any(:xrd, :xml) do
|
||||||
render xml: person_wf.to_xml, content_type: "application/xrd+xml"
|
render xml: person_wf.to_xml, content_type: "application/xrd+xml"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Creates the host-meta xml with the configured server_uri and caches it
|
# Creates the host-meta xml with the configured server_uri and caches it
|
||||||
# @return [String] XML string
|
# @return [String] XML string
|
||||||
|
|
|
||||||
3
config/initializers/mime_types.rb
Normal file
3
config/initializers/mime_types.rb
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# mime types for webfinger
|
||||||
|
Mime::Type.register "application/jrd+json", :jrd
|
||||||
|
Mime::Type.register "application/xrd+xml", :xrd
|
||||||
|
|
@ -10,7 +10,7 @@ DiasporaFederation::Engine.routes.draw do
|
||||||
|
|
||||||
controller :webfinger do
|
controller :webfinger do
|
||||||
get ".well-known/host-meta" => :host_meta, :as => "host_meta"
|
get ".well-known/host-meta" => :host_meta, :as => "host_meta"
|
||||||
get "webfinger" => :legacy_webfinger, :as => "legacy_webfinger"
|
get ".well-known/webfinger" => :webfinger, :as => "webfinger"
|
||||||
end
|
end
|
||||||
|
|
||||||
controller :h_card do
|
controller :h_card do
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ diaspora\* uses an old draft of [WebFinger][webfinger-draft] to discover users f
|
||||||
|
|
||||||
{% include warning_box.html
|
{% include warning_box.html
|
||||||
title="Old WebFinger"
|
title="Old WebFinger"
|
||||||
content="<p>diaspora* doesn't yet support the RFC 7033 WebFinger!</p>"
|
content="<p>diaspora* doesn't yet fully support the RFC 7033 WebFinger!</p>"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
## WebFinger endpoint discovery
|
## WebFinger endpoint discovery
|
||||||
|
|
@ -54,7 +54,7 @@ Content-Type: application/xrd+xml; charset=utf-8
|
||||||
~~~xml
|
~~~xml
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||||
<Link rel="lrdd" type="application/xrd+xml" template="https://example.org/webfinger?q={uri}"/>
|
<Link rel="lrdd" type="application/xrd+xml" template="https://example.org/.well-known/webfinger.xml?resource={uri}"/>
|
||||||
</XRD>
|
</XRD>
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ of the searched person.
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
GET /webfinger?q=acct:alice@example.org
|
GET /.well-known/webfinger.xml?resource=acct:alice@example.org
|
||||||
Host: example.org
|
Host: example.org
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
|
@ -117,6 +117,7 @@ Content-Type: application/xrd+xml; charset=utf-8
|
||||||
* [RFC 6415: Web Host Metadata][host-meta]
|
* [RFC 6415: Web Host Metadata][host-meta]
|
||||||
* [WebFinger draft][webfinger-draft]
|
* [WebFinger draft][webfinger-draft]
|
||||||
* [Extensible Resource Descriptor (XRD) Version 1.0][xrd]
|
* [Extensible Resource Descriptor (XRD) Version 1.0][xrd]
|
||||||
|
* [RFC 7033: WebFinger][webfinger-rfc]
|
||||||
|
|
||||||
[host-meta]: https://tools.ietf.org/html/rfc6415
|
[host-meta]: https://tools.ietf.org/html/rfc6415
|
||||||
[webfinger-draft]: https://tools.ietf.org/html/draft-jones-appsawg-webfinger-06
|
[webfinger-draft]: https://tools.ietf.org/html/draft-jones-appsawg-webfinger-06
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
|
|
||||||
# URL fragment to append to the base URL
|
# URL fragment to append to the base URL
|
||||||
WEBFINGER_SUFFIX = "/webfinger?q={uri}".freeze
|
WEBFINGER_SUFFIX = "/.well-known/webfinger.xml?resource={uri}".freeze
|
||||||
|
|
||||||
# Returns the WebFinger URL that was used to build this instance (either from
|
# Returns the WebFinger URL that was used to build this instance (either from
|
||||||
# xml or by giving a base URL).
|
# xml or by giving a base URL).
|
||||||
|
|
|
||||||
|
|
@ -107,15 +107,11 @@ module DiasporaFederation
|
||||||
# Creates the XML string from the current WebFinger instance
|
# Creates the XML string from the current WebFinger instance
|
||||||
# @return [String] XML string
|
# @return [String] XML string
|
||||||
def to_xml
|
def to_xml
|
||||||
doc = XrdDocument.new
|
to_xrd.to_xml
|
||||||
|
end
|
||||||
|
|
||||||
doc.subject = acct_uri
|
def to_json
|
||||||
doc.aliases.concat(additional_data[:aliases]) if additional_data[:aliases]
|
to_xrd.to_json
|
||||||
doc.properties.merge!(additional_data[:properties]) if additional_data[:properties]
|
|
||||||
|
|
||||||
add_links_to(doc)
|
|
||||||
|
|
||||||
doc.to_xml
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a WebFinger instance from the given XML string
|
# Creates a WebFinger instance from the given XML string
|
||||||
|
|
@ -159,6 +155,16 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_xrd
|
||||||
|
XrdDocument.new.tap do |xrd|
|
||||||
|
xrd.subject = acct_uri
|
||||||
|
xrd.aliases.concat(additional_data[:aliases]) if additional_data[:aliases]
|
||||||
|
xrd.properties.merge!(additional_data[:properties]) if additional_data[:properties]
|
||||||
|
|
||||||
|
add_links_to(xrd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def add_links_to(doc)
|
def add_links_to(doc)
|
||||||
doc.links << {rel: REL_HCARD, type: "text/html", href: hcard_url}
|
doc.links << {rel: REL_HCARD, type: "text/html", href: hcard_url}
|
||||||
doc.links << {rel: REL_SEED, type: "text/html", href: seed_url}
|
doc.links << {rel: REL_SEED, type: "text/html", href: seed_url}
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,9 @@ module DiasporaFederation
|
||||||
def to_xml
|
def to_xml
|
||||||
Nokogiri::XML::Builder.new(encoding: "UTF-8") {|xml|
|
Nokogiri::XML::Builder.new(encoding: "UTF-8") {|xml|
|
||||||
xml.XRD("xmlns" => XMLNS) {
|
xml.XRD("xmlns" => XMLNS) {
|
||||||
xml.Expires(@expires.strftime(DATETIME_FORMAT)) if @expires.instance_of?(DateTime)
|
xml.Expires(expires.strftime(DATETIME_FORMAT)) if expires.instance_of?(DateTime)
|
||||||
|
|
||||||
xml.Subject(@subject) if !@subject.nil? && !@subject.empty?
|
xml.Subject(subject) if !subject.nil? && !subject.empty?
|
||||||
|
|
||||||
add_aliases_to(xml)
|
add_aliases_to(xml)
|
||||||
add_properties_to(xml)
|
add_properties_to(xml)
|
||||||
|
|
@ -80,6 +80,16 @@ module DiasporaFederation
|
||||||
}.to_xml
|
}.to_xml
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_json
|
||||||
|
{
|
||||||
|
subject: subject,
|
||||||
|
expires: expires,
|
||||||
|
aliases: (aliases if aliases.any?),
|
||||||
|
links: (links if links.any?),
|
||||||
|
properties: (properties if properties.any?)
|
||||||
|
}.reject {|_, v| v.nil? }
|
||||||
|
end
|
||||||
|
|
||||||
# Parse the XRD document from the given string and create a hash containing
|
# Parse the XRD document from the given string and create a hash containing
|
||||||
# the extracted data.
|
# the extracted data.
|
||||||
#
|
#
|
||||||
|
|
@ -107,23 +117,26 @@ module DiasporaFederation
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
attr_reader :expires
|
||||||
|
attr_reader :subject
|
||||||
|
|
||||||
NS = {xrd: XMLNS}.freeze
|
NS = {xrd: XMLNS}.freeze
|
||||||
|
|
||||||
def add_aliases_to(xml)
|
def add_aliases_to(xml)
|
||||||
@aliases.each do |a|
|
aliases.each do |a|
|
||||||
next if !a.instance_of?(String) || a.empty?
|
next if !a.instance_of?(String) || a.empty?
|
||||||
xml.Alias(a.to_s)
|
xml.Alias(a.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_properties_to(xml)
|
def add_properties_to(xml)
|
||||||
@properties.each do |type, val|
|
properties.each do |type, val|
|
||||||
xml.Property(val.to_s, type: type)
|
xml.Property(val.to_s, type: type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_links_to(xml)
|
def add_links_to(xml)
|
||||||
@links.each do |l|
|
links.each do |l|
|
||||||
attrs = {}
|
attrs = {}
|
||||||
LINK_ATTRS.each do |attr|
|
LINK_ATTRS.each do |attr|
|
||||||
attrs[attr.to_s] = l[attr] if l.key?(attr)
|
attrs[attr.to_s] = l[attr] if l.key?(attr)
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ module DiasporaFederation
|
||||||
public_key: alice.serialized_public_key
|
public_key: alice.serialized_public_key
|
||||||
).to_xml
|
).to_xml
|
||||||
|
|
||||||
get :legacy_webfinger, q: alice.diaspora_id
|
get :webfinger, format: :xml, resource: alice.diaspora_id
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
expect(response.body).to eq(webfinger_xrd)
|
expect(response.body).to eq(webfinger_xrd)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "404s when the person does not exist" do
|
it "404s when the person does not exist" do
|
||||||
get :legacy_webfinger, q: "me@mydiaspora.pod.com"
|
get :webfinger, format: :xml, resource: "me@mydiaspora.pod.com"
|
||||||
expect(response).to be_not_found
|
expect(response).to be_not_found
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ module DiasporaFederation
|
||||||
|
|
||||||
it "contains the webfinger-template" do
|
it "contains the webfinger-template" do
|
||||||
get :host_meta
|
get :host_meta
|
||||||
expect(response.body).to include "template=\"http://localhost:3000/webfinger?q={uri}\""
|
expect(response.body).to include "template=\"http://localhost:3000/.well-known/webfinger.xml?resource={uri}\""
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a application/xrd+xml" do
|
it "returns a application/xrd+xml" do
|
||||||
|
|
@ -35,31 +35,88 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET #legacy_webfinger", rails: 5 do
|
describe "GET #webfinger", rails: 5 do
|
||||||
|
it "uses the JRD format as default" do
|
||||||
|
get :webfinger, params: {resource: alice.diaspora_id}
|
||||||
|
expect(response).to be_success
|
||||||
|
expect(response.header["Content-Type"]).to include "application/jrd+json"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "json", exceptions: :catch do
|
||||||
it "succeeds when the person exists" do
|
it "succeeds when the person exists" do
|
||||||
get :legacy_webfinger, params: {q: alice.diaspora_id}
|
get :webfinger, format: :json, params: {resource: alice.diaspora_id}
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
it "succeeds with 'acct:' in the query when the person exists" do
|
it "succeeds with 'acct:' in the query when the person exists" do
|
||||||
get :legacy_webfinger, params: {q: "acct:#{alice.diaspora_id}"}
|
get :webfinger, format: :json, params: {resource: "acct:#{alice.diaspora_id}"}
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
it "contains the diaspora* ID" do
|
it "contains the diaspora* ID" do
|
||||||
get :legacy_webfinger, params: {q: "acct:#{alice.diaspora_id}"}
|
get :webfinger, format: :json, params: {resource: "acct:#{alice.diaspora_id}"}
|
||||||
expect(response.body).to include "<Subject>acct:alice@localhost:3000</Subject>"
|
expect(response.body).to include "\"subject\": \"acct:alice@localhost:3000\""
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a application/jrd+json" do
|
||||||
|
get :webfinger, format: :json, params: {resource: "acct:#{alice.diaspora_id}"}
|
||||||
|
expect(response.header["Content-Type"]).to include "application/jrd+json"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "adds a Access-Control-Allow-Origin header" do
|
||||||
|
get :webfinger, format: :json, params: {resource: "acct:#{alice.diaspora_id}"}
|
||||||
|
expect(response.header["Access-Control-Allow-Origin"]).to eq("*")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "404s when the person does not exist" do
|
it "404s when the person does not exist" do
|
||||||
get :legacy_webfinger, params: {q: "me@mydiaspora.pod.com"}
|
get :webfinger, format: :json, params: {resource: "me@mydiaspora.pod.com"}
|
||||||
|
expect(response).to be_not_found
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises when the resource parameter is missing" do
|
||||||
|
expect {
|
||||||
|
get :webfinger, format: :json
|
||||||
|
}.to raise_error ActionController::ParameterMissing, "param is missing or the value is empty: resource"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "calls the fetch_person_for_webfinger callback" do
|
||||||
|
expect_callback(:fetch_person_for_webfinger, "alice@localhost:3000").and_call_original
|
||||||
|
|
||||||
|
get :webfinger, format: :json, params: {resource: "acct:alice@localhost:3000"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "xml" do
|
||||||
|
it "succeeds when the person exists" do
|
||||||
|
get :webfinger, format: :json, params: {resource: alice.diaspora_id}
|
||||||
|
expect(response).to be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it "succeeds with 'acct:' in the query when the person exists" do
|
||||||
|
get :webfinger, format: :xml, params: {resource: "acct:#{alice.diaspora_id}"}
|
||||||
|
expect(response).to be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
it "contains the diaspora* ID" do
|
||||||
|
get :webfinger, format: :xml, params: {resource: "acct:#{alice.diaspora_id}"}
|
||||||
|
expect(response.body).to include "<Subject>acct:alice@localhost:3000</Subject>"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a application/xrd+xml" do
|
||||||
|
get :webfinger, format: :xml, params: {resource: "acct:#{alice.diaspora_id}"}
|
||||||
|
expect(response.header["Content-Type"]).to include "application/xrd+xml"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "404s when the person does not exist" do
|
||||||
|
get :webfinger, format: :xml, params: {resource: "me@mydiaspora.pod.com"}
|
||||||
expect(response).to be_not_found
|
expect(response).to be_not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
it "calls the fetch_person_for_webfinger callback" do
|
it "calls the fetch_person_for_webfinger callback" do
|
||||||
expect_callback(:fetch_person_for_webfinger, "alice@localhost:3000").and_call_original
|
expect_callback(:fetch_person_for_webfinger, "alice@localhost:3000").and_call_original
|
||||||
|
|
||||||
get :legacy_webfinger, params: {q: "acct:alice@localhost:3000"}
|
get :webfinger, format: :xml, params: {resource: "acct:alice@localhost:3000"}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ module DiasporaFederation
|
||||||
it "fetches the userdata and returns a person object" do
|
it "fetches the userdata and returns a person object" do
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
.to_return(status: 200, body: host_meta_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}")
|
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
.to_return(status: 200, body: webfinger_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||||
.to_return(status: 200, body: hcard_html)
|
.to_return(status: 200, body: hcard_html)
|
||||||
|
|
@ -76,7 +76,7 @@ module DiasporaFederation
|
||||||
it "fetches the userdata and saves the person object via callback" do
|
it "fetches the userdata and saves the person object via callback" do
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
.to_return(status: 200, body: host_meta_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}")
|
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
.to_return(status: 200, body: webfinger_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||||
.to_return(status: 200, body: hcard_html)
|
.to_return(status: 200, body: hcard_html)
|
||||||
|
|
@ -96,7 +96,7 @@ module DiasporaFederation
|
||||||
.to_return(status: 404)
|
.to_return(status: 404)
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
.to_return(status: 200, body: host_meta_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}")
|
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
.to_return(status: 200, body: webfinger_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||||
.to_return(status: 200, body: hcard_html)
|
.to_return(status: 200, body: hcard_html)
|
||||||
|
|
@ -113,7 +113,7 @@ module DiasporaFederation
|
||||||
.to_raise(OpenSSL::SSL::SSLError)
|
.to_raise(OpenSSL::SSL::SSLError)
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
.to_return(status: 200, body: host_meta_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}")
|
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
.to_return(status: 200, body: webfinger_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||||
.to_return(status: 200, body: hcard_html)
|
.to_return(status: 200, body: hcard_html)
|
||||||
|
|
@ -130,7 +130,7 @@ module DiasporaFederation
|
||||||
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
.to_return(status: 200, body: host_meta_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}")
|
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||||
.to_return(status: 200, body: modified_webfinger)
|
.to_return(status: 200, body: modified_webfinger)
|
||||||
|
|
||||||
expect { Discovery::Discovery.new(account).fetch_and_save }.to raise_error Discovery::DiscoveryError
|
expect { Discovery::Discovery.new(account).fetch_and_save }.to raise_error Discovery::DiscoveryError
|
||||||
|
|
@ -139,7 +139,7 @@ module DiasporaFederation
|
||||||
it "fails if the diaspora* ID was not found" do
|
it "fails if the diaspora* ID was not found" do
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
.to_return(status: 200, body: host_meta_xrd)
|
||||||
stub_request(:get, "http://localhost:3000/webfinger?q=acct:#{account}")
|
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||||
.to_return(status: 404)
|
.to_return(status: 404)
|
||||||
|
|
||||||
expect { Discovery::Discovery.new(account).fetch_and_save }.to raise_error Discovery::DiscoveryError
|
expect { Discovery::Discovery.new(account).fetch_and_save }.to raise_error Discovery::DiscoveryError
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ module DiasporaFederation
|
||||||
let(:xml) { <<-XML }
|
let(:xml) { <<-XML }
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||||
<Link rel="lrdd" type="application/xrd+xml" template="#{base_url}webfinger?q={uri}"/>
|
<Link rel="lrdd" type="application/xrd+xml" template="#{base_url}.well-known/webfinger.xml?resource={uri}"/>
|
||||||
</XRD>
|
</XRD>
|
||||||
XML
|
XML
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ XML
|
||||||
context "parsing" do
|
context "parsing" do
|
||||||
it "parses its own output" do
|
it "parses its own output" do
|
||||||
hm = Discovery::HostMeta.from_xml(xml)
|
hm = Discovery::HostMeta.from_xml(xml)
|
||||||
expect(hm.webfinger_template_url).to eq("#{base_url}webfinger?q={uri}")
|
expect(hm.webfinger_template_url).to eq("#{base_url}.well-known/webfinger.xml?resource={uri}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "also reads old-style XML" do
|
it "also reads old-style XML" do
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,31 @@ XML
|
||||||
it_behaves_like "an Entity subclass"
|
it_behaves_like "an Entity subclass"
|
||||||
|
|
||||||
context "generation" do
|
context "generation" do
|
||||||
|
let(:minimal_data) { {acct_uri: acct, hcard_url: person.hcard_url, seed_url: person.url} }
|
||||||
|
let(:additional_data) {
|
||||||
|
{
|
||||||
|
aliases: [person.alias_url, person.profile_url],
|
||||||
|
properties: {"http://webfinger.example/ns/name" => "Bob Smith"},
|
||||||
|
links: [
|
||||||
|
{rel: "http://portablecontacts.net/spec/1.0", href: "https://pod.example.tld/poco/trouble"},
|
||||||
|
{
|
||||||
|
rel: "http://webfinger.net/rel/avatar",
|
||||||
|
type: "image/jpeg",
|
||||||
|
href: "http://localhost:3000/assets/user/default.png"
|
||||||
|
},
|
||||||
|
{rel: "http://openid.net/specs/connect/1.0/issuer", href: "https://pod.example.tld/"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context "xml" do
|
||||||
it "creates a nice XML document" do
|
it "creates a nice XML document" do
|
||||||
wf = Discovery::WebFinger.new(data, aliases: [person.alias_url])
|
wf = Discovery::WebFinger.new(data, aliases: [person.alias_url])
|
||||||
expect(wf.to_xml).to eq(xml)
|
expect(wf.to_xml).to eq(xml)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates minimal XML document" do
|
it "creates minimal XML document" do
|
||||||
wf = Discovery::WebFinger.new(
|
wf = Discovery::WebFinger.new(minimal_data)
|
||||||
acct_uri: acct,
|
|
||||||
hcard_url: person.hcard_url,
|
|
||||||
seed_url: person.url
|
|
||||||
)
|
|
||||||
expect(wf.to_xml).to eq(minimal_xml)
|
expect(wf.to_xml).to eq(minimal_xml)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -70,27 +84,123 @@ XML
|
||||||
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="#{person.url}"/>
|
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="#{person.url}"/>
|
||||||
<Link rel="http://portablecontacts.net/spec/1.0" href="https://pod.example.tld/poco/trouble"/>
|
<Link rel="http://portablecontacts.net/spec/1.0" href="https://pod.example.tld/poco/trouble"/>
|
||||||
<Link rel="http://webfinger.net/rel/avatar" type="image/jpeg" href="http://localhost:3000/assets/user/default.png"/>
|
<Link rel="http://webfinger.net/rel/avatar" type="image/jpeg" href="http://localhost:3000/assets/user/default.png"/>
|
||||||
|
<Link rel="http://openid.net/specs/connect/1.0/issuer" href="https://pod.example.tld/"/>
|
||||||
</XRD>
|
</XRD>
|
||||||
XML
|
XML
|
||||||
|
|
||||||
wf = Discovery::WebFinger.new(
|
wf = Discovery::WebFinger.new(minimal_data, additional_data)
|
||||||
|
expect(wf.to_xml).to eq(xml_with_additional_data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "json" do
|
||||||
|
it "creates a nice JSON document" do
|
||||||
|
json = <<-JSON
|
||||||
{
|
{
|
||||||
acct_uri: acct,
|
"subject": "#{acct}",
|
||||||
hcard_url: person.hcard_url,
|
"aliases": [
|
||||||
seed_url: person.url
|
"#{person.alias_url}"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "http://microformats.org/profile/hcard",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.hcard_url}"
|
||||||
},
|
},
|
||||||
aliases: [person.alias_url, person.profile_url],
|
|
||||||
properties: {"http://webfinger.example/ns/name" => "Bob Smith"},
|
|
||||||
links: [
|
|
||||||
{rel: "http://portablecontacts.net/spec/1.0", href: "https://pod.example.tld/poco/trouble"},
|
|
||||||
{
|
{
|
||||||
rel: "http://webfinger.net/rel/avatar",
|
"rel": "http://joindiaspora.com/seed_location",
|
||||||
type: "image/jpeg",
|
"type": "text/html",
|
||||||
href: "http://localhost:3000/assets/user/default.png"
|
"href": "#{person.url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/profile-page",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.profile_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://schemas.google.com/g/2010#updates-from",
|
||||||
|
"type": "application/atom+xml",
|
||||||
|
"href": "#{person.atom_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "salmon",
|
||||||
|
"href": "#{person.salmon_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
|
"template": "http://somehost:3000/people?q={uri}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
)
|
}
|
||||||
expect(wf.to_xml).to eq(xml_with_additional_data)
|
JSON
|
||||||
|
wf = Discovery::WebFinger.new(data, aliases: [person.alias_url])
|
||||||
|
expect(JSON.pretty_generate(wf.to_json)).to eq(json.strip)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates minimal JSON document" do
|
||||||
|
minimal_json = <<-JSON
|
||||||
|
{
|
||||||
|
"subject": "#{acct}",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "http://microformats.org/profile/hcard",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.hcard_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://joindiaspora.com/seed_location",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.url}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
wf = Discovery::WebFinger.new(minimal_data)
|
||||||
|
expect(JSON.pretty_generate(wf.to_json)).to eq(minimal_json.strip)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates JSON document with additional data" do
|
||||||
|
json_with_additional_data = <<-JSON
|
||||||
|
{
|
||||||
|
"subject": "#{acct}",
|
||||||
|
"aliases": [
|
||||||
|
"#{person.alias_url}",
|
||||||
|
"#{person.profile_url}"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "http://microformats.org/profile/hcard",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.hcard_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://joindiaspora.com/seed_location",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://portablecontacts.net/spec/1.0",
|
||||||
|
"href": "https://pod.example.tld/poco/trouble"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/avatar",
|
||||||
|
"type": "image/jpeg",
|
||||||
|
"href": "http://localhost:3000/assets/user/default.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://openid.net/specs/connect/1.0/issuer",
|
||||||
|
"href": "https://pod.example.tld/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"http://webfinger.example/ns/name": "Bob Smith"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
|
||||||
|
wf = Discovery::WebFinger.new(minimal_data, additional_data)
|
||||||
|
expect(JSON.pretty_generate(wf.to_json)).to eq(json_with_additional_data.strip)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,8 @@ XML
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context "generation" do
|
let(:doc) {
|
||||||
it "creates the xml document" do
|
Discovery::XrdDocument.new.tap do |doc|
|
||||||
doc = Discovery::XrdDocument.new
|
|
||||||
doc.expires = data[:expires]
|
doc.expires = data[:expires]
|
||||||
doc.subject = data[:subject]
|
doc.subject = data[:subject]
|
||||||
|
|
||||||
|
|
@ -62,15 +61,25 @@ XML
|
||||||
data[:links].each do |h|
|
data[:links].each do |h|
|
||||||
doc.links << h
|
doc.links << h
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
describe "#to_xml" do
|
||||||
|
it "creates the xml document" do
|
||||||
expect(doc.to_xml).to eq(xml)
|
expect(doc.to_xml).to eq(xml)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "parsing" do
|
describe "#to_json" do
|
||||||
|
it "provides the hash for json" do
|
||||||
|
expect(doc.to_json).to eq(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".xml_data" do
|
||||||
it "reads the xml document" do
|
it "reads the xml document" do
|
||||||
doc = Discovery::XrdDocument.xml_data(xml)
|
hash = Discovery::XrdDocument.xml_data(xml)
|
||||||
expect(doc).to eq(data)
|
expect(hash).to eq(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises InvalidDocument if the xml is empty" do
|
it "raises InvalidDocument if the xml is empty" do
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ module DiasporaFederation
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "routes GET legacy webfinger" do
|
it "routes GET webfinger" do
|
||||||
expect(get: "/webfinger").to route_to(
|
expect(get: "/.well-known/webfinger").to route_to(
|
||||||
controller: "diaspora_federation/webfinger",
|
controller: "diaspora_federation/webfinger",
|
||||||
action: "legacy_webfinger"
|
action: "webfinger"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue