Merge pull request #61 from SuperTux88/improve-webfinger
Improve WebFinger generation
This commit is contained in:
commit
a759340e22
4 changed files with 94 additions and 44 deletions
|
|
@ -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
|
|
||||||
|
|
||||||
# @!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
|
||||||
|
|
@ -50,7 +44,7 @@ module DiasporaFederation
|
||||||
|
|
||||||
# @!attribute [r] profile_url
|
# @!attribute [r] profile_url
|
||||||
# @return [String] link to the users profile
|
# @return [String] link to the users profile
|
||||||
property :profile_url, :string
|
property :profile_url, :string, default: nil
|
||||||
|
|
||||||
# @!attribute [r] atom_url
|
# @!attribute [r] atom_url
|
||||||
# This atom feed is an Activity Stream of the user's public posts. diaspora*
|
# This atom feed is an Activity Stream of the user's public posts. diaspora*
|
||||||
|
|
@ -61,18 +55,18 @@ module DiasporaFederation
|
||||||
# Note that this feed MAY also be made available through the PubSubHubbub
|
# Note that this feed MAY also be made available through the PubSubHubbub
|
||||||
# mechanism by supplying a <link rel="hub"> in the atom feed itself.
|
# mechanism by supplying a <link rel="hub"> in the atom feed itself.
|
||||||
# @return [String] atom feed url
|
# @return [String] atom feed url
|
||||||
property :atom_url, :string
|
property :atom_url, :string, default: nil
|
||||||
|
|
||||||
# @!attribute [r] salmon_url
|
# @!attribute [r] salmon_url
|
||||||
# @note could be nil
|
# @note could be nil
|
||||||
# @return [String] salmon endpoint url
|
# @return [String] salmon endpoint url
|
||||||
# @see https://cdn.rawgit.com/salmon-protocol/salmon-protocol/master/draft-panzer-salmon-00.html#SMLR
|
# @see https://cdn.rawgit.com/salmon-protocol/salmon-protocol/master/draft-panzer-salmon-00.html#SMLR
|
||||||
# Panzer draft for Salmon, paragraph 3.3
|
# Panzer draft for Salmon, paragraph 3.3
|
||||||
property :salmon_url, :string
|
property :salmon_url, :string, default: nil
|
||||||
|
|
||||||
# @!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
|
property :subscribe_url, :string, default: nil
|
||||||
|
|
||||||
# +hcard_url+ link relation
|
# +hcard_url+ link relation
|
||||||
REL_HCARD = "http://microformats.org/profile/hcard".freeze
|
REL_HCARD = "http://microformats.org/profile/hcard".freeze
|
||||||
|
|
@ -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.aliases << @alias_url
|
doc.subject = acct_uri
|
||||||
|
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),
|
||||||
|
|
@ -147,14 +160,20 @@ module DiasporaFederation
|
||||||
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}
|
||||||
|
|
||||||
doc.links << {rel: REL_PROFILE, type: "text/html", href: @profile_url}
|
add_optional_links_to(doc)
|
||||||
doc.links << {rel: REL_ATOM, type: "application/atom+xml", href: @atom_url}
|
|
||||||
doc.links << {rel: REL_SALMON, href: @salmon_url}
|
|
||||||
|
|
||||||
doc.links << {rel: REL_SUBSCRIBE, template: @subscribe_url}
|
doc.links.concat(additional_data[:links]) if additional_data[:links]
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_optional_links_to(doc)
|
||||||
|
doc.links << {rel: REL_PROFILE, type: "text/html", href: profile_url} if profile_url
|
||||||
|
doc.links << {rel: REL_ATOM, type: "application/atom+xml", href: atom_url} if atom_url
|
||||||
|
doc.links << {rel: REL_SALMON, href: salmon_url} if salmon_url
|
||||||
|
|
||||||
|
doc.links << {rel: REL_SUBSCRIBE, template: subscribe_url} if subscribe_url
|
||||||
end
|
end
|
||||||
|
|
||||||
private_class_method def self.find_link(links, rel)
|
private_class_method def self.find_link(links, rel)
|
||||||
|
|
@ -170,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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
@ -29,6 +28,15 @@ module DiasporaFederation
|
||||||
<Link rel="salmon" href="#{person.salmon_url}"/>
|
<Link rel="salmon" href="#{person.salmon_url}"/>
|
||||||
<Link rel="http://ostatus.org/schema/1.0/subscribe" template="#{person.subscribe_url}"/>
|
<Link rel="http://ostatus.org/schema/1.0/subscribe" template="#{person.subscribe_url}"/>
|
||||||
</XRD>
|
</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
|
XML
|
||||||
|
|
||||||
let(:string) { "WebFinger:#{data[:acct_uri]}" }
|
let(:string) { "WebFinger:#{data[:acct_uri]}" }
|
||||||
|
|
@ -37,16 +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
|
||||||
|
wf = Discovery::WebFinger.new(
|
||||||
|
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
|
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)
|
||||||
|
|
@ -56,14 +107,6 @@ XML
|
||||||
end
|
end
|
||||||
|
|
||||||
it "reads minimal xml" do
|
it "reads minimal xml" do
|
||||||
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
|
|
||||||
wf = Discovery::WebFinger.from_xml(minimal_xml)
|
wf = Discovery::WebFinger.from_xml(minimal_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(person.hcard_url)
|
||||||
|
|
@ -124,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)
|
||||||
|
|
@ -167,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)
|
||||||
|
|
|
||||||
|
|
@ -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 }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue