Remove legacy Webfinger handling
This commit is contained in:
parent
3861eb9fef
commit
d5107f5678
12 changed files with 341 additions and 767 deletions
|
|
@ -5,20 +5,6 @@ require_dependency "diaspora_federation/application_controller"
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
# This controller handles all webfinger-specific requests.
|
# This controller handles all webfinger-specific requests.
|
||||||
class WebfingerController < ApplicationController
|
class WebfingerController < ApplicationController
|
||||||
# Returns the host-meta xml
|
|
||||||
#
|
|
||||||
# example:
|
|
||||||
# <?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
# <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
# <Link rel="lrdd" type="application/xrd+xml"
|
|
||||||
# template="https://server.example/.well-known/webfinger.xml?resource={uri}"/>
|
|
||||||
# </XRD>
|
|
||||||
#
|
|
||||||
# GET /.well-known/host-meta
|
|
||||||
def host_meta
|
|
||||||
render xml: WebfingerController.host_meta_xml, content_type: "application/xrd+xml"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the webfinger as RFC 7033 JRD or XRD.
|
# Returns the webfinger as RFC 7033 JRD or XRD.
|
||||||
#
|
#
|
||||||
# JSON example:
|
# JSON example:
|
||||||
|
|
@ -59,20 +45,6 @@ module DiasporaFederation
|
||||||
# ]
|
# ]
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# XML example:
|
|
||||||
# <?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
# <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
# <Subject>acct:alice@localhost:3000</Subject>
|
|
||||||
# <Alias>http://localhost:3000/people/c8e87290f6a20132963908fbffceb188</Alias>
|
|
||||||
# <Link rel="http://microformats.org/profile/hcard" type="text/html"
|
|
||||||
# href="http://localhost:3000/hcard/users/c8e87290f6a20132963908fbffceb188"/>
|
|
||||||
# <Link rel="http://joindiaspora.com/seed_location" type="text/html" href="http://localhost:3000/"/>
|
|
||||||
# <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"
|
|
||||||
# href="http://localhost:3000/public/alice.atom"/>
|
|
||||||
# <Link rel="salmon" href="http://localhost:3000/receive/users/c8e87290f6a20132963908fbffceb188"/>
|
|
||||||
# </XRD>
|
|
||||||
#
|
|
||||||
# GET /.well-known/webfinger?resource=<uri>
|
# GET /.well-known/webfinger?resource=<uri>
|
||||||
def webfinger
|
def webfinger
|
||||||
person_wf = find_person_webfinger(params.require(:resource))
|
person_wf = find_person_webfinger(params.require(:resource))
|
||||||
|
|
@ -80,24 +52,11 @@ module DiasporaFederation
|
||||||
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"] = "*"
|
headers["Access-Control-Allow-Origin"] = "*"
|
||||||
render json: JSON.pretty_generate(person_wf.to_json), content_type: "application/jrd+json"
|
render json: JSON.pretty_generate(person_wf.to_json), content_type: "application/jrd+json"
|
||||||
end
|
end
|
||||||
format.any(:xrd, :xml) do
|
|
||||||
render xml: person_wf.to_xml, content_type: "application/xrd+xml"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates the host-meta xml with the configured server_uri and caches it
|
|
||||||
# @return [String] XML string
|
|
||||||
def self.host_meta_xml
|
|
||||||
@host_meta_xml ||= Discovery::HostMeta.from_base_url(DiasporaFederation.server_uri.to_s).to_xml
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ DiasporaFederation::Engine.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
controller :webfinger do
|
controller :webfinger do
|
||||||
get ".well-known/host-meta" => :host_meta, :as => "host_meta"
|
|
||||||
get ".well-known/webfinger" => :webfinger, :as => "webfinger"
|
get ".well-known/webfinger" => :webfinger, :as => "webfinger"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ end
|
||||||
|
|
||||||
require "diaspora_federation/discovery/exceptions"
|
require "diaspora_federation/discovery/exceptions"
|
||||||
require "diaspora_federation/discovery/xrd_document"
|
require "diaspora_federation/discovery/xrd_document"
|
||||||
require "diaspora_federation/discovery/host_meta"
|
|
||||||
require "diaspora_federation/discovery/web_finger"
|
require "diaspora_federation/discovery/web_finger"
|
||||||
require "diaspora_federation/discovery/h_card"
|
require "diaspora_federation/discovery/h_card"
|
||||||
require "diaspora_federation/discovery/discovery"
|
require "diaspora_federation/discovery/discovery"
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ module DiasporaFederation
|
||||||
validate_diaspora_id
|
validate_diaspora_id
|
||||||
|
|
||||||
DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person)
|
DiasporaFederation.callbacks.trigger(:save_person_after_webfinger, person)
|
||||||
logger.info "successfully webfingered #{diaspora_id}"
|
logger.info "Successfully webfingered #{diaspora_id}"
|
||||||
person
|
person
|
||||||
rescue DiscoveryError
|
rescue DiscoveryError
|
||||||
raise # simply re-raise DiscoveryError
|
raise # simply re-raise DiscoveryError
|
||||||
|
|
@ -67,22 +67,11 @@ module DiasporaFederation
|
||||||
"acct:#{diaspora_id}"
|
"acct:#{diaspora_id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def legacy_webfinger_url_from_host_meta
|
|
||||||
# This tries the xrd url with https first, then falls back to http.
|
|
||||||
host_meta = HostMeta.from_xml(get("https://#{domain}/.well-known/host-meta", http_fallback: true))
|
|
||||||
host_meta.webfinger_template_url.gsub("{uri}", acct_parameter)
|
|
||||||
end
|
|
||||||
|
|
||||||
def webfinger
|
def webfinger
|
||||||
return @webfinger if @webfinger
|
|
||||||
|
|
||||||
webfinger_url = "https://#{domain}/.well-known/webfinger?resource=#{acct_parameter}"
|
|
||||||
|
|
||||||
# This tries the WebFinger URL with https first, then falls back to http if webfinger_http_fallback is enabled.
|
# This tries the WebFinger URL with https first, then falls back to http if webfinger_http_fallback is enabled.
|
||||||
@webfinger = WebFinger.from_json(get(webfinger_url, http_fallback: DiasporaFederation.webfinger_http_fallback))
|
@webfinger ||=
|
||||||
rescue => e # rubocop:disable Style/RescueStandardError
|
WebFinger.from_json(get("https://#{domain}/.well-known/webfinger?resource=#{acct_parameter}",
|
||||||
logger.warn "WebFinger failed, retrying with legacy WebFinger for #{diaspora_id}: #{e.class}: #{e.message}"
|
http_fallback: DiasporaFederation.webfinger_http_fallback))
|
||||||
@webfinger = WebFinger.from_xml(get(legacy_webfinger_url_from_host_meta))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def hcard
|
def hcard
|
||||||
|
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module DiasporaFederation
|
|
||||||
module Discovery
|
|
||||||
# Generates and parses Host Meta documents.
|
|
||||||
#
|
|
||||||
# This is a minimal implementation of the standard, only to the degree of what
|
|
||||||
# is used for the purposes of the diaspora* protocol. (e.g. WebFinger)
|
|
||||||
#
|
|
||||||
# @example Creating a Host Meta document
|
|
||||||
# doc = HostMeta.from_base_url("https://pod.example.tld/")
|
|
||||||
# doc.to_xml
|
|
||||||
#
|
|
||||||
# @example Parsing a Host Meta document
|
|
||||||
# doc = HostMeta.from_xml(xml_string)
|
|
||||||
# webfinger_tpl = doc.webfinger_template_url
|
|
||||||
#
|
|
||||||
# @see http://tools.ietf.org/html/rfc6415 RFC 6415: "Web Host Metadata"
|
|
||||||
# @see XrdDocument
|
|
||||||
class HostMeta
|
|
||||||
private_class_method :new
|
|
||||||
|
|
||||||
# Creates a new host-meta instance
|
|
||||||
# @param [String] webfinger_url the webfinger-url
|
|
||||||
def initialize(webfinger_url)
|
|
||||||
@webfinger_url = webfinger_url
|
|
||||||
end
|
|
||||||
|
|
||||||
# URL fragment to append to the base URL
|
|
||||||
WEBFINGER_SUFFIX = "/.well-known/webfinger.xml?resource={uri}"
|
|
||||||
|
|
||||||
# Returns the WebFinger URL that was used to build this instance (either from
|
|
||||||
# xml or by giving a base URL).
|
|
||||||
# @return [String] WebFinger template URL
|
|
||||||
def webfinger_template_url
|
|
||||||
@webfinger_url
|
|
||||||
end
|
|
||||||
|
|
||||||
# Produces the XML string for the Host Meta instance with a +Link+ element
|
|
||||||
# containing the +webfinger_url+.
|
|
||||||
# @return [String] XML string
|
|
||||||
def to_xml
|
|
||||||
doc = XrdDocument.new
|
|
||||||
doc.links << {rel: "lrdd",
|
|
||||||
type: "application/xrd+xml",
|
|
||||||
template: @webfinger_url}
|
|
||||||
doc.to_xml
|
|
||||||
end
|
|
||||||
|
|
||||||
# Builds a new HostMeta instance and constructs the WebFinger URL from the
|
|
||||||
# given base URL by appending HostMeta::WEBFINGER_SUFFIX.
|
|
||||||
# @param [String, URL] base_url the base-url for the webfinger-url
|
|
||||||
# @return [HostMeta]
|
|
||||||
# @raise [InvalidData] if the webfinger url is malformed
|
|
||||||
def self.from_base_url(base_url)
|
|
||||||
webfinger_url = "#{base_url.to_s.chomp('/')}#{WEBFINGER_SUFFIX}"
|
|
||||||
raise InvalidData, "invalid webfinger url: #{webfinger_url}" unless webfinger_url_valid?(webfinger_url)
|
|
||||||
|
|
||||||
new(webfinger_url)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Reads the given Host Meta XML document string and populates the
|
|
||||||
# +webfinger_url+.
|
|
||||||
# @param [String] hostmeta_xml Host Meta XML string
|
|
||||||
# @raise [InvalidData] if the xml or the webfinger url is malformed
|
|
||||||
def self.from_xml(hostmeta_xml)
|
|
||||||
data = XrdDocument.xml_data(hostmeta_xml)
|
|
||||||
raise InvalidData, "received an invalid xml" unless data.key?(:links)
|
|
||||||
|
|
||||||
webfinger_url = webfinger_url_from_xrd(data)
|
|
||||||
raise InvalidData, "invalid webfinger url: #{webfinger_url}" unless webfinger_url_valid?(webfinger_url)
|
|
||||||
|
|
||||||
new(webfinger_url)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Applies some basic sanity-checking to the given URL
|
|
||||||
# @param [String] url validation subject
|
|
||||||
# @return [Boolean] validation result
|
|
||||||
private_class_method def self.webfinger_url_valid?(url)
|
|
||||||
!url.nil? && url.instance_of?(String) && url =~ %r{\Ahttps?://.*/.*\{uri\}.*}i
|
|
||||||
end
|
|
||||||
|
|
||||||
# Gets the webfinger url from an XRD data structure
|
|
||||||
# @param [Hash] data extracted data
|
|
||||||
# @return [String] webfinger url
|
|
||||||
private_class_method def self.webfinger_url_from_xrd(data)
|
|
||||||
link = data[:links].find {|l| l[:rel] == "lrdd" }
|
|
||||||
return link[:template] unless link.nil?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -3,10 +3,7 @@
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
module Discovery
|
module Discovery
|
||||||
# The WebFinger document used for diaspora* user discovery is based on an
|
# The WebFinger document used for diaspora* user discovery is based on an
|
||||||
# {http://tools.ietf.org/html/draft-jones-appsawg-webfinger older draft of the specification}.
|
# {https://datatracker.ietf.org/doc/html/rfc7033 RFC 7033}.
|
||||||
#
|
|
||||||
# In the meantime an actual RFC draft has been in development, which should
|
|
||||||
# serve as a base for all future changes of this implementation.
|
|
||||||
#
|
#
|
||||||
# @example Creating a WebFinger document from a person hash
|
# @example Creating a WebFinger document from a person hash
|
||||||
# wf = WebFinger.new(
|
# wf = WebFinger.new(
|
||||||
|
|
@ -17,22 +14,20 @@ module DiasporaFederation
|
||||||
# atom_url: "https://server.example/public/user.atom",
|
# atom_url: "https://server.example/public/user.atom",
|
||||||
# salmon_url: "https://server.example/receive/users/0123456789abcdef"
|
# salmon_url: "https://server.example/receive/users/0123456789abcdef"
|
||||||
# )
|
# )
|
||||||
# xml_string = wf.to_xml
|
# json_string = wf.to_json
|
||||||
#
|
#
|
||||||
# @example Creating a WebFinger instance from an xml document
|
# @example Creating a WebFinger instance from an JSON document
|
||||||
# wf = WebFinger.from_xml(xml_string)
|
# wf = WebFinger.from_json(json_string)
|
||||||
# ...
|
# ...
|
||||||
# hcard_url = wf.hcard_url
|
# hcard_url = wf.hcard_url
|
||||||
# ...
|
# ...
|
||||||
#
|
#
|
||||||
# @see http://tools.ietf.org/html/draft-jones-appsawg-webfinger "WebFinger" -
|
|
||||||
# current draft
|
|
||||||
# @see http://www.iana.org/assignments/link-relations/link-relations.xhtml
|
# @see http://www.iana.org/assignments/link-relations/link-relations.xhtml
|
||||||
# official list of IANA link relations
|
# official list of IANA link relations
|
||||||
class WebFinger < Entity
|
class WebFinger < Entity
|
||||||
# @!attribute [r] acct_uri
|
# @!attribute [r] acct_uri
|
||||||
# The Subject element should contain the webfinger address that was asked
|
# The Subject element should contain the WebFinger address that was asked
|
||||||
# for. If it does not, then this webfinger profile MUST be ignored.
|
# for. If it does not, then this WebFinger profile MUST be ignored.
|
||||||
# @return [String]
|
# @return [String]
|
||||||
property :acct_uri, :string
|
property :acct_uri, :string
|
||||||
|
|
||||||
|
|
@ -67,7 +62,7 @@ module DiasporaFederation
|
||||||
property :salmon_url, :string, optional: true
|
property :salmon_url, :string, optional: true
|
||||||
|
|
||||||
# @!attribute [r] subscribe_url
|
# @!attribute [r] subscribe_url
|
||||||
# This url is used to find another user on the home-pod of the user in the webfinger.
|
# This url is used to find another user on the home-pod of the user in the WebFinger.
|
||||||
property :subscribe_url, :string, optional: true
|
property :subscribe_url, :string, optional: true
|
||||||
|
|
||||||
# +hcard_url+ link relation
|
# +hcard_url+ link relation
|
||||||
|
|
@ -106,29 +101,29 @@ module DiasporaFederation
|
||||||
super(data)
|
super(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates the XML string from the current WebFinger instance
|
# @!visibility private
|
||||||
# @return [String] XML string
|
# Generating WebFinger to XML is not supported anymore, use {#to_json} instead.
|
||||||
def to_xml
|
def to_xml
|
||||||
to_xrd.to_xml
|
raise "Generating WebFinger to XML is not supported anymore, use 'to_json' instead."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Creates the JSON string from the current WebFinger instance
|
||||||
|
# @return [String] JSON string
|
||||||
def to_json(*_args)
|
def to_json(*_args)
|
||||||
to_xrd.to_json
|
to_xrd.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a WebFinger instance from the given XML string
|
# @!visibility private
|
||||||
# @param [String] webfinger_xml WebFinger XML string
|
# Parsing WebFinger as XML is not supported anymore, use {from_json} instead.
|
||||||
# @return [WebFinger] WebFinger instance
|
def self.from_xml(_webfinger_xml)
|
||||||
# @raise [InvalidData] if the given XML string is invalid or incomplete
|
raise "Parsing WebFinger as XML is not supported anymore, use 'from_json' instead."
|
||||||
def self.from_xml(webfinger_xml)
|
|
||||||
from_hash(parse_xml_and_validate(webfinger_xml))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a WebFinger instance from the given JSON string
|
# Creates a WebFinger instance from the given JSON string
|
||||||
# @param [String] webfinger_json WebFinger JSON string
|
# @param [String] webfinger_json WebFinger JSON string
|
||||||
# @return [WebFinger] WebFinger instance
|
# @return [WebFinger] WebFinger instance
|
||||||
def self.from_json(webfinger_json)
|
def self.from_json(webfinger_json)
|
||||||
from_hash(XrdDocument.json_data(webfinger_json))
|
from_hash(parse_json_and_validate(webfinger_json))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a WebFinger instance from the given data
|
# Creates a WebFinger instance from the given data
|
||||||
|
|
@ -157,15 +152,15 @@ module DiasporaFederation
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Parses the XML string to a Hash and does some rudimentary checking on
|
# Parses the JSON string to a Hash and does some rudimentary checking on
|
||||||
# the data Hash.
|
# the data Hash.
|
||||||
# @param [String] webfinger_xml WebFinger XML string
|
# @param [String] webfinger_json WebFinger JSON string
|
||||||
# @return [Hash] data XML data
|
# @return [Hash] data JSON data
|
||||||
# @raise [InvalidData] if the given XML string is invalid or incomplete
|
# @raise [InvalidData] if the given JSON string is invalid or incomplete
|
||||||
private_class_method def self.parse_xml_and_validate(webfinger_xml)
|
private_class_method def self.parse_json_and_validate(webfinger_json)
|
||||||
XrdDocument.xml_data(webfinger_xml).tap do |data|
|
XrdDocument.json_data(webfinger_json).tap do |data|
|
||||||
valid = data.key?(:subject) && data.key?(:links)
|
valid = data.key?(:subject) && data.key?(:links)
|
||||||
raise InvalidData, "webfinger xml is incomplete" unless valid
|
raise InvalidData, "Webfinger JSON is incomplete" unless valid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,8 @@ module DiasporaFederation
|
||||||
# This class implements basic handling of XRD documents as far as it is
|
# This class implements basic handling of XRD documents as far as it is
|
||||||
# necessary in the context of the protocols used with diaspora* federation.
|
# necessary in the context of the protocols used with diaspora* federation.
|
||||||
#
|
#
|
||||||
# @note {http://tools.ietf.org/html/rfc6415 RFC 6415} recommends that servers
|
# It also implements handling of the JRD format, see
|
||||||
# should also offer the JRD format in addition to the XRD representation.
|
# {https://datatracker.ietf.org/doc/html/rfc6415#appendix-A RFC 6415, Appendix A}
|
||||||
# Implementing +XrdDocument#to_json+ and +XrdDocument.json_data+ should
|
|
||||||
# be almost trivial due to the simplicity of the format and the way the data
|
|
||||||
# is stored internally already. See
|
|
||||||
# {http://tools.ietf.org/html/rfc6415#appendix-A RFC 6415, Appendix A}
|
|
||||||
# for a description of the JSON format.
|
# for a description of the JSON format.
|
||||||
#
|
#
|
||||||
# @example Creating a XrdDocument
|
# @example Creating a XrdDocument
|
||||||
|
|
@ -210,7 +206,7 @@ module DiasporaFederation
|
||||||
|
|
||||||
# symbolize link keys from JSON hash, but only convert known keys
|
# symbolize link keys from JSON hash, but only convert known keys
|
||||||
private_class_method def self.symbolize_keys_for_links(links)
|
private_class_method def self.symbolize_keys_for_links(links)
|
||||||
links.map do |link|
|
links&.map do |link|
|
||||||
{}.tap do |hash|
|
{}.tap do |hash|
|
||||||
LINK_ATTRS.each do |attr|
|
LINK_ATTRS.each do |attr|
|
||||||
hash[attr] = link[attr.to_s] if link.key?(attr.to_s)
|
hash[attr] = link[attr.to_s] if link.key?(attr.to_s)
|
||||||
|
|
|
||||||
|
|
@ -4,39 +4,6 @@ module DiasporaFederation
|
||||||
describe WebfingerController, type: :controller do
|
describe WebfingerController, type: :controller do
|
||||||
routes { DiasporaFederation::Engine.routes }
|
routes { DiasporaFederation::Engine.routes }
|
||||||
|
|
||||||
describe "GET #host_meta" do
|
|
||||||
before do
|
|
||||||
DiasporaFederation.server_uri = URI("http://localhost:3000/")
|
|
||||||
WebfingerController.instance_variable_set(:@host_meta_xml, nil) # clear cache
|
|
||||||
end
|
|
||||||
|
|
||||||
it "succeeds" do
|
|
||||||
get :host_meta
|
|
||||||
expect(response).to be_successful
|
|
||||||
end
|
|
||||||
|
|
||||||
it "contains the webfinger-template" do
|
|
||||||
get :host_meta
|
|
||||||
expect(response.body).to include "template=\"http://localhost:3000/.well-known/webfinger.xml?resource={uri}\""
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns a application/xrd+xml" do
|
|
||||||
get :host_meta
|
|
||||||
expect(response.header["Content-Type"]).to include "application/xrd+xml"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "calls Discovery::HostMeta.from_base_url with the base url" do
|
|
||||||
expect(Discovery::HostMeta).to receive(:from_base_url).with("http://localhost:3000/").and_call_original
|
|
||||||
get :host_meta
|
|
||||||
end
|
|
||||||
|
|
||||||
it "caches the xml" do
|
|
||||||
expect(Discovery::HostMeta).to receive(:from_base_url).exactly(1).times.and_call_original
|
|
||||||
get :host_meta
|
|
||||||
get :host_meta
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET #webfinger" do
|
describe "GET #webfinger" do
|
||||||
it "uses the JRD format as default" do
|
it "uses the JRD format as default" do
|
||||||
get :webfinger, params: {resource: alice.diaspora_id}
|
get :webfinger, params: {resource: alice.diaspora_id}
|
||||||
|
|
@ -44,7 +11,6 @@ module DiasporaFederation
|
||||||
expect(response.header["Content-Type"]).to include "application/jrd+json"
|
expect(response.header["Content-Type"]).to include "application/jrd+json"
|
||||||
end
|
end
|
||||||
|
|
||||||
context "json", exceptions: :catch do
|
|
||||||
it "succeeds when the person exists" do
|
it "succeeds when the person exists" do
|
||||||
get :webfinger, format: :json, params: {resource: alice.diaspora_id}
|
get :webfinger, format: :json, params: {resource: alice.diaspora_id}
|
||||||
expect(response).to be_successful
|
expect(response).to be_successful
|
||||||
|
|
@ -87,39 +53,5 @@ module DiasporaFederation
|
||||||
get :webfinger, format: :json, params: {resource: "acct:alice@localhost:3000"}
|
get :webfinger, format: :json, params: {resource: "acct:alice@localhost:3000"}
|
||||||
end
|
end
|
||||||
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_successful
|
|
||||||
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_successful
|
|
||||||
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
|
|
||||||
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: :xml, params: {resource: "acct:alice@localhost:3000"}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
module DiasporaFederation
|
module DiasporaFederation
|
||||||
describe Discovery::Discovery do
|
describe Discovery::Discovery do
|
||||||
let(:host_meta_xrd) { Discovery::HostMeta.from_base_url("http://localhost:3000/").to_xml }
|
subject(:discovery) { Discovery::Discovery.new(account) }
|
||||||
|
|
||||||
let(:webfinger_data) {
|
let(:webfinger_data) {
|
||||||
{
|
{
|
||||||
acct_uri: "acct:#{alice.diaspora_id}",
|
acct_uri: "acct:#{alice.diaspora_id}",
|
||||||
|
|
@ -17,9 +18,6 @@ module DiasporaFederation
|
||||||
public_key: alice.serialized_public_key
|
public_key: alice.serialized_public_key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let(:webfinger_xrd) {
|
|
||||||
DiasporaFederation::Discovery::WebFinger.new(webfinger_data).to_xml
|
|
||||||
}
|
|
||||||
let(:webfinger_jrd) {
|
let(:webfinger_jrd) {
|
||||||
JSON.pretty_generate(DiasporaFederation::Discovery::WebFinger.new(webfinger_data).to_json)
|
JSON.pretty_generate(DiasporaFederation::Discovery::WebFinger.new(webfinger_data).to_json)
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +38,6 @@ module DiasporaFederation
|
||||||
}
|
}
|
||||||
let(:account) { alice.diaspora_id }
|
let(:account) { alice.diaspora_id }
|
||||||
let(:default_image) { "http://localhost:3000/assets/user/default.png" }
|
let(:default_image) { "http://localhost:3000/assets/user/default.png" }
|
||||||
subject { Discovery::Discovery.new(account) }
|
|
||||||
|
|
||||||
describe "#intialize" do
|
describe "#intialize" do
|
||||||
it "sets diaspora* ID" do
|
it "sets diaspora* ID" do
|
||||||
|
|
@ -62,7 +59,7 @@ module DiasporaFederation
|
||||||
.to_return(status: 200, body: hcard_html)
|
.to_return(status: 200, body: hcard_html)
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||||
person = subject.fetch_and_save
|
person = discovery.fetch_and_save
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
expect(person.guid).to eq(alice.guid)
|
||||||
expect(person.diaspora_id).to eq(account)
|
expect(person.diaspora_id).to eq(account)
|
||||||
|
|
@ -93,7 +90,7 @@ module DiasporaFederation
|
||||||
callback_person = person
|
callback_person = person
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(subject.fetch_and_save).to be(callback_person)
|
expect(discovery.fetch_and_save).to be(callback_person)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "fails if the diaspora* ID does not match" do
|
it "fails if the diaspora* ID does not match" do
|
||||||
|
|
@ -102,67 +99,32 @@ module DiasporaFederation
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||||
.to_return(status: 200, body: modified_webfinger)
|
.to_return(status: 200, body: modified_webfinger)
|
||||||
|
|
||||||
expect { subject.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
expect { discovery.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
||||||
end
|
end
|
||||||
|
|
||||||
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/webfinger?resource=acct:#{account}")
|
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||||
.to_return(status: 404)
|
.to_return(status: 404)
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
|
||||||
.to_return(status: 404)
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
|
||||||
.to_return(status: 404)
|
|
||||||
|
|
||||||
expect { subject.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
expect { discovery.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
||||||
end
|
end
|
||||||
|
|
||||||
context "http fallback" do
|
context "with http fallback" do
|
||||||
context "http fallback disabled (default)" do
|
context "when http fallback disabled (default)" do
|
||||||
it "falls back to legacy WebFinger if https fails with 404" do
|
it "does not fall back to http if https fails with ssl error" do
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
|
||||||
.to_return(status: 404)
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
|
||||||
.to_return(status: 200, body: hcard_html)
|
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
|
||||||
person = subject.fetch_and_save
|
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
|
||||||
expect(person.diaspora_id).to eq(account)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "falls back to legacy WebFinger if https fails with ssl error" do
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||||
.to_raise(OpenSSL::SSL::SSLError)
|
.to_raise(OpenSSL::SSL::SSLError)
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_raise(OpenSSL::SSL::SSLError)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
|
||||||
.to_return(status: 200, body: hcard_html)
|
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
expect { discovery.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
||||||
person = subject.fetch_and_save
|
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
|
||||||
expect(person.diaspora_id).to eq(account)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "http fallback enabled" do
|
context "when http fallback enabled" do
|
||||||
before :all do
|
before do
|
||||||
DiasporaFederation.webfinger_http_fallback = true
|
DiasporaFederation.webfinger_http_fallback = true
|
||||||
end
|
end
|
||||||
|
|
||||||
after :all do
|
after do
|
||||||
DiasporaFederation.webfinger_http_fallback = false
|
DiasporaFederation.webfinger_http_fallback = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -175,7 +137,7 @@ module DiasporaFederation
|
||||||
.to_return(status: 200, body: hcard_html)
|
.to_return(status: 200, body: hcard_html)
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||||
person = subject.fetch_and_save
|
person = discovery.fetch_and_save
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
expect(person.guid).to eq(alice.guid)
|
||||||
expect(person.diaspora_id).to eq(account)
|
expect(person.diaspora_id).to eq(account)
|
||||||
|
|
@ -190,7 +152,7 @@ module DiasporaFederation
|
||||||
.to_return(status: 200, body: hcard_html)
|
.to_return(status: 200, body: hcard_html)
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||||
person = subject.fetch_and_save
|
person = discovery.fetch_and_save
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
expect(person.guid).to eq(alice.guid)
|
||||||
expect(person.diaspora_id).to eq(account)
|
expect(person.diaspora_id).to eq(account)
|
||||||
|
|
@ -198,118 +160,33 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "legacy WebFinger" do
|
context "with error handling" do
|
||||||
it "falls back to legacy WebFinger" do
|
|
||||||
incomplete_webfinger_json = "{\"links\":[{\"rel\":\"http://openid.net/specs/connect/1.0/issuer\"," \
|
|
||||||
"\"href\":\"https://localhost:3000/\"}],\"subject\":\"acct:#{account}\"}"
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: incomplete_webfinger_json)
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
|
||||||
.to_return(status: 200, body: hcard_html)
|
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
|
||||||
person = subject.fetch_and_save
|
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
|
||||||
expect(person.diaspora_id).to eq(account)
|
|
||||||
expect(person.url).to eq(alice.url)
|
|
||||||
expect(person.exported_key).to eq(alice.serialized_public_key)
|
|
||||||
|
|
||||||
profile = person.profile
|
|
||||||
|
|
||||||
expect(profile.diaspora_id).to eq(alice.diaspora_id)
|
|
||||||
expect(profile.first_name).to eq("Dummy")
|
|
||||||
expect(profile.last_name).to eq("User")
|
|
||||||
|
|
||||||
expect(profile.image_url).to eq(default_image)
|
|
||||||
expect(profile.image_url_medium).to eq(default_image)
|
|
||||||
expect(profile.image_url_small).to eq(default_image)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "falls back to http if https fails with 404" do
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
|
||||||
.to_return(status: 404)
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 404)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
|
||||||
.to_return(status: 200, body: hcard_html)
|
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
|
||||||
person = subject.fetch_and_save
|
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
|
||||||
expect(person.diaspora_id).to eq(account)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "falls back to http if https fails with ssl error" do
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
|
||||||
.to_raise(OpenSSL::SSL::SSLError)
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_raise(OpenSSL::SSL::SSLError)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: webfinger_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
|
||||||
.to_return(status: 200, body: hcard_html)
|
|
||||||
|
|
||||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
|
||||||
person = subject.fetch_and_save
|
|
||||||
|
|
||||||
expect(person.guid).to eq(alice.guid)
|
|
||||||
expect(person.diaspora_id).to eq(account)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "fails if the diaspora* ID does not match" do
|
|
||||||
modified_webfinger = webfinger_xrd.gsub(account, "anonther_user@example.com")
|
|
||||||
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: "foobar")
|
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
|
||||||
.to_return(status: 200, body: host_meta_xrd)
|
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
|
||||||
.to_return(status: 200, body: modified_webfinger)
|
|
||||||
|
|
||||||
expect { subject.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "error handling" do
|
|
||||||
it "re-raises DiscoveryError" do
|
it "re-raises DiscoveryError" do
|
||||||
expect(subject).to receive(:validate_diaspora_id)
|
expect(discovery).to receive(:validate_diaspora_id)
|
||||||
.and_raise(Discovery::DiscoveryError, "Something went wrong!")
|
.and_raise(Discovery::DiscoveryError, "Something went wrong!")
|
||||||
|
|
||||||
expect { subject.fetch_and_save }.to raise_error Discovery::DiscoveryError, "Something went wrong!"
|
expect { discovery.fetch_and_save }.to raise_error Discovery::DiscoveryError, "Something went wrong!"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "re-raises InvalidDocument" do
|
it "re-raises InvalidDocument" do
|
||||||
expect(subject).to receive(:validate_diaspora_id)
|
expect(discovery).to receive(:validate_diaspora_id)
|
||||||
.and_raise(Discovery::InvalidDocument, "Wrong document!")
|
.and_raise(Discovery::InvalidDocument, "Wrong document!")
|
||||||
|
|
||||||
expect { subject.fetch_and_save }.to raise_error Discovery::InvalidDocument, "Wrong document!"
|
expect { discovery.fetch_and_save }.to raise_error Discovery::InvalidDocument, "Wrong document!"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "re-raises InvalidData" do
|
it "re-raises InvalidData" do
|
||||||
expect(subject).to receive(:validate_diaspora_id)
|
expect(discovery).to receive(:validate_diaspora_id)
|
||||||
.and_raise(Discovery::InvalidData, "Wrong data!")
|
.and_raise(Discovery::InvalidData, "Wrong data!")
|
||||||
|
|
||||||
expect { subject.fetch_and_save }.to raise_error Discovery::InvalidData, "Wrong data!"
|
expect { discovery.fetch_and_save }.to raise_error Discovery::InvalidData, "Wrong data!"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a DiscoveryError when an unhandled error occurs" do
|
it "raises a DiscoveryError when an unhandled error occurs" do
|
||||||
expect(subject).to receive(:validate_diaspora_id)
|
allow(discovery).to receive(:validate_diaspora_id).and_raise("OMG! EVERYTHING IS BROKEN!")
|
||||||
.and_raise("OMG! EVERYTHING IS BROKEN!")
|
|
||||||
|
|
||||||
expect {
|
expect {
|
||||||
subject.fetch_and_save
|
discovery.fetch_and_save
|
||||||
}.to raise_error Discovery::DiscoveryError,
|
}.to raise_error Discovery::DiscoveryError,
|
||||||
"Failed discovery for #{account}: RuntimeError: OMG! EVERYTHING IS BROKEN!"
|
"Failed discovery for #{account}: RuntimeError: OMG! EVERYTHING IS BROKEN!"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module DiasporaFederation
|
|
||||||
describe Discovery::HostMeta do
|
|
||||||
let(:base_url) { "https://pod.example.tld/" }
|
|
||||||
let(:xml) { <<~XML }
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<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.xml?resource={uri}"/>
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
|
|
||||||
it "must not create blank instances" do
|
|
||||||
expect { Discovery::HostMeta.new }.to raise_error NoMethodError
|
|
||||||
end
|
|
||||||
|
|
||||||
context "generation" do
|
|
||||||
it "creates a nice XML document" do
|
|
||||||
hm = Discovery::HostMeta.from_base_url(base_url)
|
|
||||||
expect(hm.to_xml).to eq(xml)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "converts object to string" do
|
|
||||||
hm = Discovery::HostMeta.from_base_url(URI(base_url))
|
|
||||||
expect(hm.to_xml).to eq(xml)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "appends a '/' if necessary" do
|
|
||||||
hm = Discovery::HostMeta.from_base_url("https://pod.example.tld")
|
|
||||||
expect(hm.to_xml).to eq(xml)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "fails if the base_url was omitted" do
|
|
||||||
expect { Discovery::HostMeta.from_base_url("") }.to raise_error Discovery::InvalidData
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "parsing" do
|
|
||||||
it "parses its own output" do
|
|
||||||
hm = Discovery::HostMeta.from_xml(xml)
|
|
||||||
expect(hm.webfinger_template_url).to eq("#{base_url}.well-known/webfinger.xml?resource={uri}")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "also reads old-style XML" do
|
|
||||||
historic_xml = <<~XML
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
|
|
||||||
<!-- Resource-specific Information -->
|
|
||||||
|
|
||||||
<Link rel="lrdd"
|
|
||||||
type="application/xrd+xml"
|
|
||||||
template="#{base_url}webfinger?q={uri}" />
|
|
||||||
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
hm = Discovery::HostMeta.from_xml(historic_xml)
|
|
||||||
expect(hm.webfinger_template_url).to eq("#{base_url}webfinger?q={uri}")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "also reads friendica/redmatrix XML" do
|
|
||||||
friendica_redmatrix_xml = <<~XML
|
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'
|
|
||||||
xmlns:hm='http://host-meta.net/xrd/1.0'>
|
|
||||||
|
|
||||||
<hm:Host>pod.example.tld</hm:Host>
|
|
||||||
|
|
||||||
<Link rel='lrdd' template='#{base_url}xrd/?uri={uri}' />
|
|
||||||
<Link rel="http://oexchange.org/spec/0.8/rel/resident-target" type="application/xrd+xml"
|
|
||||||
href="https://pod.example.tld/oexchange/xrd" />
|
|
||||||
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
hm = Discovery::HostMeta.from_xml(friendica_redmatrix_xml)
|
|
||||||
expect(hm.webfinger_template_url).to eq("#{base_url}xrd/?uri={uri}")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "fails if the document does not contain a webfinger url" do
|
|
||||||
invalid_xml = <<~XML
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
expect { Discovery::HostMeta.from_xml(invalid_xml) }.to raise_error Discovery::InvalidData
|
|
||||||
end
|
|
||||||
|
|
||||||
it "fails if the document contains a malformed webfinger url" do
|
|
||||||
invalid_xml = <<~XML
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
<Link rel="lrdd" type="application/xrd+xml" template="#{base_url}webfinger?q="/>
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
expect { Discovery::HostMeta.from_xml(invalid_xml) }.to raise_error Discovery::InvalidData
|
|
||||||
end
|
|
||||||
|
|
||||||
it "fails if the document is invalid" do
|
|
||||||
expect { Discovery::HostMeta.from_xml("") }.to raise_error Discovery::InvalidDocument
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -18,29 +18,6 @@ module DiasporaFederation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let(:xml) { <<~XML }
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
<Subject>#{acct}</Subject>
|
|
||||||
<Alias>#{person.alias_url}</Alias>
|
|
||||||
<Link rel="http://microformats.org/profile/hcard" type="text/html" href="#{person.hcard_url}"/>
|
|
||||||
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="#{person.url}"/>
|
|
||||||
<Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="#{person.profile_url}"/>
|
|
||||||
<Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="#{person.atom_url}"/>
|
|
||||||
<Link rel="salmon" href="#{person.salmon_url}"/>
|
|
||||||
<Link rel="http://ostatus.org/schema/1.0/subscribe" template="#{person.subscribe_url}"/>
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
|
|
||||||
let(:minimal_xml) { <<~XML }
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
<Subject>#{acct}</Subject>
|
|
||||||
<Link rel="http://microformats.org/profile/hcard" type="text/html" href="#{person.hcard_url}"/>
|
|
||||||
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="#{person.url}"/>
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
|
|
||||||
let(:json) { <<~JSON }
|
let(:json) { <<~JSON }
|
||||||
{
|
{
|
||||||
"subject": "#{acct}",
|
"subject": "#{acct}",
|
||||||
|
|
@ -74,7 +51,7 @@ module DiasporaFederation
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
"template": "http://somehost:3000/people?q={uri}"
|
"template": "#{person.url}people?q={uri}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +79,7 @@ module DiasporaFederation
|
||||||
|
|
||||||
it_behaves_like "an Entity subclass"
|
it_behaves_like "an Entity subclass"
|
||||||
|
|
||||||
context "generation" do
|
context "when generating" do
|
||||||
let(:minimal_data) { {acct_uri: acct, hcard_url: person.hcard_url, seed_url: person.url} }
|
let(:minimal_data) { {acct_uri: acct, hcard_url: person.hcard_url, seed_url: person.url} }
|
||||||
let(:additional_data) {
|
let(:additional_data) {
|
||||||
{
|
{
|
||||||
|
|
@ -120,39 +97,6 @@ module DiasporaFederation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context "xml" do
|
|
||||||
it "creates a nice XML document" do
|
|
||||||
wf = Discovery::WebFinger.new(data, aliases: [person.alias_url])
|
|
||||||
expect(wf.to_xml).to eq(xml)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates minimal XML document" do
|
|
||||||
wf = Discovery::WebFinger.new(minimal_data)
|
|
||||||
expect(wf.to_xml).to eq(minimal_xml)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates XML document with additional data" do
|
|
||||||
xml_with_additional_data = <<~XML
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
|
||||||
<Subject>#{acct}</Subject>
|
|
||||||
<Alias>#{person.alias_url}</Alias>
|
|
||||||
<Alias>#{person.profile_url}</Alias>
|
|
||||||
<Property type="http://webfinger.example/ns/name">Bob Smith</Property>
|
|
||||||
<Link rel="http://microformats.org/profile/hcard" type="text/html" href="#{person.hcard_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://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>
|
|
||||||
XML
|
|
||||||
|
|
||||||
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
|
it "creates a nice JSON document" do
|
||||||
wf = Discovery::WebFinger.new(data, aliases: [person.alias_url])
|
wf = Discovery::WebFinger.new(data, aliases: [person.alias_url])
|
||||||
expect(JSON.pretty_generate(wf.to_json)).to eq(json.strip)
|
expect(JSON.pretty_generate(wf.to_json)).to eq(json.strip)
|
||||||
|
|
@ -205,28 +149,14 @@ module DiasporaFederation
|
||||||
wf = Discovery::WebFinger.new(minimal_data, additional_data)
|
wf = Discovery::WebFinger.new(minimal_data, additional_data)
|
||||||
expect(JSON.pretty_generate(wf.to_json)).to eq(json_with_additional_data.strip)
|
expect(JSON.pretty_generate(wf.to_json)).to eq(json_with_additional_data.strip)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not support XML anymore" do
|
||||||
|
expect { Discovery::WebFinger.new(minimal_data).to_xml }
|
||||||
|
.to raise_error "Generating WebFinger to XML is not supported anymore, use 'to_json' instead."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "parsing" do
|
context "when parsing" do
|
||||||
it "reads its own xml output" do
|
|
||||||
wf = Discovery::WebFinger.from_xml(xml)
|
|
||||||
expect(wf.acct_uri).to eq(acct)
|
|
||||||
expect(wf.hcard_url).to eq(person.hcard_url)
|
|
||||||
expect(wf.seed_url).to eq(person.url)
|
|
||||||
expect(wf.profile_url).to eq(person.profile_url)
|
|
||||||
expect(wf.atom_url).to eq(person.atom_url)
|
|
||||||
expect(wf.salmon_url).to eq(person.salmon_url)
|
|
||||||
expect(wf.subscribe_url).to eq(person.subscribe_url)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "reads minimal xml" do
|
|
||||||
wf = Discovery::WebFinger.from_xml(minimal_xml)
|
|
||||||
expect(wf.acct_uri).to eq(acct)
|
|
||||||
expect(wf.hcard_url).to eq(person.hcard_url)
|
|
||||||
expect(wf.seed_url).to eq(person.url)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "reads its own json output" do
|
it "reads its own json output" do
|
||||||
wf = Discovery::WebFinger.from_json(json)
|
wf = Discovery::WebFinger.from_json(json)
|
||||||
expect(wf.acct_uri).to eq(acct)
|
expect(wf.acct_uri).to eq(acct)
|
||||||
|
|
@ -246,119 +176,219 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is frozen after parsing" do
|
it "is frozen after parsing" do
|
||||||
wf = Discovery::WebFinger.from_xml(xml)
|
wf = Discovery::WebFinger.from_json(json)
|
||||||
expect(wf).to be_frozen
|
expect(wf).to be_frozen
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reads friendica XML (two aliases, first with acct)" do
|
it "reads friendica JSON" do
|
||||||
friendica_xml = <<~XML
|
friendica_hcard_url = "#{person.url}hcard/#{person.nickname}"
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
friendica_profile_url = "#{person.url}profile/#{person.nickname}"
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
friendica_atom_url = "#{person.url}dfrn_poll/#{person.nickname}"
|
||||||
|
friendica_salmon_url = "#{person.url}salmon/#{person.nickname}"
|
||||||
|
friendica_subscribe_url = "#{person.url}follow?url={uri}"
|
||||||
|
|
||||||
<Subject>#{acct}</Subject>
|
friendica_json = <<~JSON
|
||||||
<Alias>#{acct}</Alias>
|
{
|
||||||
<Alias>#{person.alias_url}</Alias>
|
"subject": "#{acct}",
|
||||||
|
"aliases": [
|
||||||
|
"#{person.url}~#{person.nickname}",
|
||||||
|
"#{friendica_profile_url}"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "http://purl.org/macgirvin/dfrn/1.0",
|
||||||
|
"href": "#{person.url}profile/#{person.nickname}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://schemas.google.com/g/2010#updates-from",
|
||||||
|
"type": "application/atom+xml",
|
||||||
|
"href": "#{friendica_atom_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/profile-page",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{friendica_profile_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"type": "application/activity+json",
|
||||||
|
"href": "#{friendica_profile_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://microformats.org/profile/hcard",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{friendica_hcard_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://portablecontacts.net/spec/1.0",
|
||||||
|
"href": "#{person.url}poco/#{person.nickname}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/avatar",
|
||||||
|
"type": "image/png",
|
||||||
|
"href": "#{person.url}photo/profile/#{person.nickname}.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://joindiaspora.com/seed_location",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "salmon",
|
||||||
|
"href": "#{friendica_salmon_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://salmon-protocol.org/ns/salmon-replies",
|
||||||
|
"href": "#{friendica_salmon_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://salmon-protocol.org/ns/salmon-mention",
|
||||||
|
"href": "#{friendica_salmon_url}/mention"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
|
"template": "#{person.url}follow?url={uri}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "magic-public-key",
|
||||||
|
"href": "data:application/magic-public-key,RSA.abcdef1234567890"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://purl.org/openwebauth/v1",
|
||||||
|
"type": "application/x-zot+json",
|
||||||
|
"href": "#{person.url}owa"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
|
||||||
<Link rel="http://purl.org/macgirvin/dfrn/1.0"
|
wf = Discovery::WebFinger.from_json(friendica_json)
|
||||||
href="#{person.profile_url}" />
|
|
||||||
<Link rel="http://schemas.google.com/g/2010#updates-from"
|
|
||||||
type="application/atom+xml"
|
|
||||||
href="#{person.atom_url}" />
|
|
||||||
<Link rel="http://webfinger.net/rel/profile-page"
|
|
||||||
type="text/html"
|
|
||||||
href="#{person.profile_url}" />
|
|
||||||
<Link rel="http://microformats.org/profile/hcard"
|
|
||||||
type="text/html"
|
|
||||||
href="#{person.hcard_url}" />
|
|
||||||
<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://joindiaspora.com/seed_location" type="text/html" href="#{person.url}" />
|
|
||||||
<Link rel="http://joindiaspora.com/guid" type="text/html" href="#{person.guid}" />
|
|
||||||
<Link rel="diaspora-public-key" type="RSA" href="#{public_key_base64}" />
|
|
||||||
|
|
||||||
<Link rel="salmon"
|
|
||||||
href="#{person.salmon_url}" />
|
|
||||||
<Link rel="http://salmon-protocol.org/ns/salmon-replies"
|
|
||||||
href="https://pod.example.tld/salmon/trouble" />
|
|
||||||
<Link rel="http://salmon-protocol.org/ns/salmon-mention"
|
|
||||||
href="https://pod.example.tld/salmon/trouble/mention" />
|
|
||||||
<Link rel="http://ostatus.org/schema/1.0/subscribe"
|
|
||||||
template="https://pod.example.tld/follow?url={uri}" />
|
|
||||||
<Link rel="magic-public-key"
|
|
||||||
href="data:application/magic-public-key,RSA.abcdef1234567890" />
|
|
||||||
|
|
||||||
<Property xmlns:mk="http://salmon-protocol.org/ns/magic-key"
|
|
||||||
type="http://salmon-protocol.org/ns/magic-key"
|
|
||||||
mk:key_id="1">RSA.abcdef1234567890</Property>
|
|
||||||
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
|
|
||||||
wf = Discovery::WebFinger.from_xml(friendica_xml)
|
|
||||||
expect(wf.acct_uri).to eq(acct)
|
expect(wf.acct_uri).to eq(acct)
|
||||||
expect(wf.hcard_url).to eq(person.hcard_url)
|
expect(wf.hcard_url).to eq(friendica_hcard_url)
|
||||||
expect(wf.seed_url).to eq(person.url)
|
expect(wf.seed_url).to eq(person.url)
|
||||||
expect(wf.profile_url).to eq(person.profile_url)
|
expect(wf.profile_url).to eq(friendica_profile_url)
|
||||||
expect(wf.atom_url).to eq(person.atom_url)
|
expect(wf.atom_url).to eq(friendica_atom_url)
|
||||||
expect(wf.salmon_url).to eq(person.salmon_url)
|
expect(wf.salmon_url).to eq(friendica_salmon_url)
|
||||||
expect(wf.subscribe_url).to eq("https://pod.example.tld/follow?url={uri}")
|
expect(wf.subscribe_url).to eq(friendica_subscribe_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reads redmatrix XML (no alias)" do
|
it "reads hubzilla JSON" do
|
||||||
redmatrix_xml = <<~XML
|
hubzilla_hcard_url = "#{person.url}hcard/#{person.nickname}"
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
hubzilla_profile_url = "#{person.url}profile/#{person.nickname}"
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
hubzilla_atom_url = "#{person.url}ofeed/#{person.nickname}"
|
||||||
|
hubzilla_subscribe_url = "#{person.url}follow?f=&url={uri}"
|
||||||
|
|
||||||
<Subject>#{person.diaspora_id}</Subject>
|
hubzilla_json = <<~JSON
|
||||||
|
{
|
||||||
|
"subject": "#{acct}",
|
||||||
|
"aliases": [
|
||||||
|
"#{person.url}channel/#{person.nickname}",
|
||||||
|
"#{person.url}~#{person.nickname}",
|
||||||
|
"#{person.url}@#{person.nickname}"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"http://webfinger.net/ns/name": "#{person.full_name}",
|
||||||
|
"http://xmlns.com/foaf/0.1/name": "#{person.full_name}",
|
||||||
|
"https://w3id.org/security/v1#publicKeyPem": #{person.serialized_public_key.dump},
|
||||||
|
"http://purl.org/zot/federation": "zot6,zot,activitypub,diaspora"
|
||||||
|
},
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/avatar",
|
||||||
|
"type": "image/jpeg",
|
||||||
|
"href": "#{person.url}photo/profile/l/2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://microformats.org/profile/hcard",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{hubzilla_hcard_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://openid.net/specs/connect/1.0/issuer",
|
||||||
|
"href": "#{person.url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/profile-page",
|
||||||
|
"href": "#{hubzilla_profile_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://schemas.google.com/g/2010#updates-from",
|
||||||
|
"type": "application/atom+xml",
|
||||||
|
"href": "#{hubzilla_atom_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/blog",
|
||||||
|
"href": "#{person.url}channel/#{person.nickname}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
|
"template": "#{hubzilla_subscribe_url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://purl.org/zot/protocol/6.0",
|
||||||
|
"type": "application/x-zot+json",
|
||||||
|
"href": "#{person.url}channel/#{person.nickname}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://purl.org/zot/protocol",
|
||||||
|
"href": "#{person.url}.well-known/zot-info?address=#{person.nickname}@#{person.diaspora_id.split('@')[1]}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://purl.org/openwebauth/v1",
|
||||||
|
"type": "application/x-zot+json",
|
||||||
|
"href": "#{person.url}owa"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "magic-public-key",
|
||||||
|
"href": "data:application/magic-public-key,RSA.abcdef1234567890"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"type": "application/ld+json; profile=\\\"https://www.w3.org/ns/activitystreams\\\"",
|
||||||
|
"href": "#{person.url}channel/#{person.nickname}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"type": "application/activity+json",
|
||||||
|
"href": "#{person.url}channel/#{person.nickname}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://joindiaspora.com/seed_location",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "#{person.url}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "salmon",
|
||||||
|
"href": "#{person.salmon_url}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
JSON
|
||||||
|
|
||||||
<Link rel="http://schemas.google.com/g/2010#updates-from"
|
wf = Discovery::WebFinger.from_json(hubzilla_json)
|
||||||
type="application/atom+xml"
|
expect(wf.acct_uri).to eq(acct)
|
||||||
href="#{person.atom_url}" />
|
expect(wf.hcard_url).to eq(hubzilla_hcard_url)
|
||||||
<Link rel="http://webfinger.net/rel/profile-page"
|
|
||||||
type="text/html"
|
|
||||||
href="#{person.profile_url}" />
|
|
||||||
<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://microformats.org/profile/hcard"
|
|
||||||
type="text/html"
|
|
||||||
href="#{person.hcard_url}" />
|
|
||||||
|
|
||||||
<Link rel="magic-public-key"
|
|
||||||
href="data:application/magic-public-key,RSA.abcdef1234567890" />
|
|
||||||
|
|
||||||
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="#{person.url}" />
|
|
||||||
<Link rel="http://joindiaspora.com/guid" type="text/html" href="#{person.guid}" />
|
|
||||||
<Link rel="diaspora-public-key" type="RSA" href="#{public_key_base64}" />
|
|
||||||
|
|
||||||
</XRD>
|
|
||||||
XML
|
|
||||||
|
|
||||||
wf = Discovery::WebFinger.from_xml(redmatrix_xml)
|
|
||||||
expect(wf.acct_uri).to eq(person.diaspora_id)
|
|
||||||
expect(wf.hcard_url).to eq(person.hcard_url)
|
|
||||||
expect(wf.seed_url).to eq(person.url)
|
expect(wf.seed_url).to eq(person.url)
|
||||||
expect(wf.profile_url).to eq(person.profile_url)
|
expect(wf.profile_url).to eq(hubzilla_profile_url)
|
||||||
expect(wf.atom_url).to eq(person.atom_url)
|
expect(wf.atom_url).to eq(hubzilla_atom_url)
|
||||||
expect(wf.salmon_url).to be_nil
|
expect(wf.salmon_url).to eq(person.salmon_url)
|
||||||
|
expect(wf.subscribe_url).to eq(hubzilla_subscribe_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "fails if the document is empty" do
|
it "fails if the document is empty" do
|
||||||
invalid_xml = <<~XML
|
invalid_json = <<~JSON
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
{}
|
||||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
JSON
|
||||||
</XRD>
|
expect { Discovery::WebFinger.from_json(invalid_json) }.to raise_error Discovery::InvalidData
|
||||||
XML
|
|
||||||
expect { Discovery::WebFinger.from_xml(invalid_xml) }.to raise_error Discovery::InvalidData
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "fails if the document is not XML" do
|
it "fails if the document is not JSON" do
|
||||||
expect { Discovery::WebFinger.from_xml("") }.to raise_error Discovery::InvalidDocument
|
expect { Discovery::WebFinger.from_json("") }.to raise_error Discovery::InvalidDocument
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not support XML anymore" do
|
||||||
|
expect { Discovery::WebFinger.from_xml("") }
|
||||||
|
.to raise_error "Parsing WebFinger as XML is not supported anymore, use 'from_json' instead."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,6 @@ module DiasporaFederation
|
||||||
describe ReceiveController, type: :routing do
|
describe ReceiveController, type: :routing do
|
||||||
routes { DiasporaFederation::Engine.routes }
|
routes { DiasporaFederation::Engine.routes }
|
||||||
|
|
||||||
it "routes GET host-meta" do
|
|
||||||
expect(get: ".well-known/host-meta").to route_to(
|
|
||||||
controller: "diaspora_federation/webfinger",
|
|
||||||
action: "host_meta"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "routes GET webfinger" do
|
it "routes GET webfinger" do
|
||||||
expect(get: "/.well-known/webfinger").to route_to(
|
expect(get: "/.well-known/webfinger").to route_to(
|
||||||
controller: "diaspora_federation/webfinger",
|
controller: "diaspora_federation/webfinger",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue