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
# wf = WebFinger.new(
# acct_uri: "acct:user@server.example",
# alias_url: "https://server.example/people/0123456789abcdef",
# hcard_url: "https://server.example/hcard/users/user",
# seed_url: "https://server.example/",
# profile_url: "https://server.example/u/user",
@ -35,11 +34,6 @@ module DiasporaFederation
# @return [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
# @return [String] link to the +hCard+
property :hcard_url, :string
@ -93,12 +87,31 @@ module DiasporaFederation
# +subscribe_url+ link relation
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
# @return [String] XML string
def to_xml
doc = XrdDocument.new
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)
@ -116,7 +129,7 @@ module DiasporaFederation
new(
acct_uri: data[:subject],
alias_url: parse_alias(data[:aliases]),
hcard_url: parse_link(links, REL_HCARD),
seed_url: parse_link(links, REL_SEED),
profile_url: parse_link(links, REL_PROFILE),
@ -151,6 +164,8 @@ module DiasporaFederation
doc.links << {rel: REL_SEED, type: "text/html", href: seed_url}
add_optional_links_to(doc)
doc.links.concat(additional_data[:links]) if additional_data[:links]
end
def add_optional_links_to(doc)
@ -174,15 +189,6 @@ module DiasporaFederation
element = find_link(links, rel)
element ? element[:template] : nil
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

View file

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

View file

@ -6,8 +6,7 @@ module DiasporaFederation
let(:data) {
{
acct_uri: "acct:#{person.diaspora_id}",
alias_url: person.alias_url,
acct_uri: acct,
hcard_url: person.hcard_url,
seed_url: person.url,
profile_url: person.profile_url,
@ -46,25 +45,59 @@ XML
context "generation" 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)
end
it "creates minimal XML document" do
wf = Discovery::WebFinger.new(
acct_uri: "acct:#{person.diaspora_id}",
acct_uri: acct,
hcard_url: person.hcard_url,
seed_url: person.url
)
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"/>
</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
context "parsing" do
it "reads its own output" do
wf = Discovery::WebFinger.from_xml(xml)
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.seed_url).to eq(person.url)
expect(wf.profile_url).to eq(person.profile_url)
@ -134,7 +167,6 @@ XML
wf = Discovery::WebFinger.from_xml(friendica_xml)
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.seed_url).to eq(person.url)
expect(wf.profile_url).to eq(person.profile_url)
@ -177,7 +209,6 @@ XML
wf = Discovery::WebFinger.from_xml(redmatrix_xml)
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.seed_url).to eq(person.url)
expect(wf.profile_url).to eq(person.profile_url)

View file

@ -23,7 +23,7 @@ module DiasporaFederation
end
# 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
it_behaves_like "a property with a value validation/restriction" do
let(:property) { prop }