Allow to generate WebFinger with additional data

This allows projects to use this library to generate the WebFinger
document when they already need WebFinger for other elements.

Also removed the explicit alias_url, aliases can now be added with
{aliases: [alias_url]} as second parameter.
This commit is contained in:
Benjamin Neff 2017-04-27 03:33:06 +02:00
parent 5fef7633c3
commit 1b9dfc812e
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
4 changed files with 62 additions and 26 deletions

View file

@ -9,7 +9,6 @@ module DiasporaFederation
# @example Creating a WebFinger document from a person hash # @example Creating a WebFinger document from a person hash
# wf = WebFinger.new( # wf = WebFinger.new(
# acct_uri: "acct:user@server.example", # acct_uri: "acct:user@server.example",
# alias_url: "https://server.example/people/0123456789abcdef",
# hcard_url: "https://server.example/hcard/users/user", # hcard_url: "https://server.example/hcard/users/user",
# seed_url: "https://server.example/", # seed_url: "https://server.example/",
# profile_url: "https://server.example/u/user", # profile_url: "https://server.example/u/user",
@ -35,11 +34,6 @@ module DiasporaFederation
# @return [String] # @return [String]
property :acct_uri, :string property :acct_uri, :string
# @!attribute [r] alias_url
# @note could be nil
# @return [String] link to the users profile
property :alias_url, :string, default: nil
# @!attribute [r] hcard_url # @!attribute [r] hcard_url
# @return [String] link to the +hCard+ # @return [String] link to the +hCard+
property :hcard_url, :string property :hcard_url, :string
@ -93,12 +87,31 @@ module DiasporaFederation
# +subscribe_url+ link relation # +subscribe_url+ link relation
REL_SUBSCRIBE = "http://ostatus.org/schema/1.0/subscribe".freeze REL_SUBSCRIBE = "http://ostatus.org/schema/1.0/subscribe".freeze
# Additional WebFinger data
# @return [Hash] additional elements
attr_reader :additional_data
# Initializes a new WebFinger Entity
#
# @param [Hash] data WebFinger data
# @param [Hash] additional_data additional WebFinger data
# @option additional_data [Array<String>] :aliases additional aliases
# @option additional_data [Hash] :properties properties
# @option additional_data [Array<Hash>] :links additional link elements
# @see DiasporaFederation::Entity#initialize
def initialize(data, additional_data={})
@additional_data = additional_data
super(data)
end
# 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 doc = XrdDocument.new
doc.subject = acct_uri doc.subject = acct_uri
doc.aliases << alias_url doc.aliases.concat(additional_data[:aliases]) if additional_data[:aliases]
doc.properties.merge!(additional_data[:properties]) if additional_data[:properties]
add_links_to(doc) add_links_to(doc)
@ -116,7 +129,7 @@ module DiasporaFederation
new( new(
acct_uri: data[:subject], acct_uri: data[:subject],
alias_url: parse_alias(data[:aliases]),
hcard_url: parse_link(links, REL_HCARD), hcard_url: parse_link(links, REL_HCARD),
seed_url: parse_link(links, REL_SEED), seed_url: parse_link(links, REL_SEED),
profile_url: parse_link(links, REL_PROFILE), profile_url: parse_link(links, REL_PROFILE),
@ -151,6 +164,8 @@ module DiasporaFederation
doc.links << {rel: REL_SEED, type: "text/html", href: seed_url} doc.links << {rel: REL_SEED, type: "text/html", href: seed_url}
add_optional_links_to(doc) add_optional_links_to(doc)
doc.links.concat(additional_data[:links]) if additional_data[:links]
end end
def add_optional_links_to(doc) def add_optional_links_to(doc)
@ -174,15 +189,6 @@ module DiasporaFederation
element = find_link(links, rel) element = find_link(links, rel)
element ? element[:template] : nil element ? element[:template] : nil
end end
# This method is used to parse the alias_url from the XML.
# * redmatrix has sometimes no alias, return nil
# * old pods had quotes around the alias url, this can be removed later
# * friendica has two aliases and the first is with "acct:": return only an URL starting with http (or https)
private_class_method def self.parse_alias(aliases)
return nil unless aliases
aliases.find {|a| a.start_with?("http") }
end
end end
end end
end end

View file

@ -9,7 +9,6 @@ module DiasporaFederation
rule :acct_uri, :not_empty rule :acct_uri, :not_empty
rule :alias_url, URI: %i(host path)
rule :hcard_url, [:not_nil, URI: %i(host path)] rule :hcard_url, [:not_nil, URI: %i(host path)]
rule :seed_url, %i(not_nil URI) rule :seed_url, %i(not_nil URI)
rule :profile_url, URI: %i(host path) rule :profile_url, URI: %i(host path)

View file

@ -6,8 +6,7 @@ module DiasporaFederation
let(:data) { let(:data) {
{ {
acct_uri: "acct:#{person.diaspora_id}", acct_uri: acct,
alias_url: person.alias_url,
hcard_url: person.hcard_url, hcard_url: person.hcard_url,
seed_url: person.url, seed_url: person.url,
profile_url: person.profile_url, profile_url: person.profile_url,
@ -46,25 +45,59 @@ XML
context "generation" do context "generation" do
it "creates a nice XML document" do it "creates a nice XML document" do
wf = Discovery::WebFinger.new(data) 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(
acct_uri: "acct:#{person.diaspora_id}", acct_uri: acct,
hcard_url: person.hcard_url, hcard_url: person.hcard_url,
seed_url: person.url seed_url: person.url
) )
expect(wf.to_xml).to eq(minimal_xml) expect(wf.to_xml).to eq(minimal_xml)
end 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"/>
</XRD>
XML
wf = Discovery::WebFinger.new(
{
acct_uri: acct,
hcard_url: person.hcard_url,
seed_url: person.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",
type: "image/jpeg",
href: "http://localhost:3000/assets/user/default.png"
}
]
)
expect(wf.to_xml).to eq(xml_with_additional_data)
end
end end
context "parsing" do context "parsing" do
it "reads its own output" do it "reads its own output" do
wf = Discovery::WebFinger.from_xml(xml) wf = Discovery::WebFinger.from_xml(xml)
expect(wf.acct_uri).to eq(acct) expect(wf.acct_uri).to eq(acct)
expect(wf.alias_url).to eq(person.alias_url)
expect(wf.hcard_url).to eq(person.hcard_url) 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(person.profile_url)
@ -134,7 +167,6 @@ XML
wf = Discovery::WebFinger.from_xml(friendica_xml) wf = Discovery::WebFinger.from_xml(friendica_xml)
expect(wf.acct_uri).to eq(acct) expect(wf.acct_uri).to eq(acct)
expect(wf.alias_url).to eq(person.alias_url)
expect(wf.hcard_url).to eq(person.hcard_url) 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(person.profile_url)
@ -177,7 +209,6 @@ XML
wf = Discovery::WebFinger.from_xml(redmatrix_xml) wf = Discovery::WebFinger.from_xml(redmatrix_xml)
expect(wf.acct_uri).to eq(person.diaspora_id) expect(wf.acct_uri).to eq(person.diaspora_id)
expect(wf.alias_url).to be_nil
expect(wf.hcard_url).to eq(person.hcard_url) 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(person.profile_url)

View file

@ -23,7 +23,7 @@ module DiasporaFederation
end end
# optional urls # optional urls
%i(alias_url salmon_url profile_url atom_url).each do |prop| %i(salmon_url profile_url atom_url).each do |prop|
describe "##{prop}" do describe "##{prop}" do
it_behaves_like "a property with a value validation/restriction" do it_behaves_like "a property with a value validation/restriction" do
let(:property) { prop } let(:property) { prop }