use person object with attributes to generate webfinger
This commit is contained in:
parent
3354eb472b
commit
6e6171fc93
8 changed files with 94 additions and 128 deletions
|
|
@ -155,3 +155,10 @@ Metrics/AbcSize:
|
|||
|
||||
Metrics/ModuleLength:
|
||||
Max: 1500
|
||||
|
||||
Style/SingleLineMethods:
|
||||
Exclude:
|
||||
- "test/dummy/app/models/*"
|
||||
Style/EmptyLineBetweenDefs:
|
||||
Exclude:
|
||||
- "test/dummy/app/models/*"
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ module DiasporaFederation
|
|||
return render nothing: true, status: 404 if person.nil?
|
||||
|
||||
logger.info "webfinger profile request for: #{person.diaspora_handle}"
|
||||
render body: WebFinger::WebFinger.from_person(person.webfinger_hash).to_xml, content_type: "application/xrd+xml"
|
||||
render body: WebFinger::WebFinger.from_person(person).to_xml, content_type: "application/xrd+xml"
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -86,7 +86,15 @@ module DiasporaFederation
|
|||
validate_class(@person_class, "person_class", %i(
|
||||
find_local_by_diaspora_handle
|
||||
find_local_by_guid
|
||||
webfinger_hash
|
||||
diaspora_handle
|
||||
alias_url
|
||||
hcard_url
|
||||
seed_url
|
||||
profile_url
|
||||
atom_url
|
||||
salmon_url
|
||||
guid
|
||||
public_key
|
||||
hcard_profile_hash
|
||||
))
|
||||
logger.info "successfully configured the federation engine"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ module DiasporaFederation
|
|||
# Raised, if something is wrong with the webfinger data
|
||||
#
|
||||
# * if the +webfinger_url+ is missing or malformed in {HostMeta.from_base_url} or {HostMeta.from_xml}
|
||||
# * if the +data+ given to {WebFinger.from_person} is an invalid type or doesn't contain all required entries
|
||||
# * if the parsed XML from {WebFinger.from_xml} is incomplete
|
||||
# * if the params passed to {HCard.from_profile} or {HCard.from_html}
|
||||
# are in some way malformed, invalid or incomplete.
|
||||
|
|
|
|||
|
|
@ -9,19 +9,19 @@ module DiasporaFederation
|
|||
# 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 account data
|
||||
# wf = WebFinger.from_person({
|
||||
# acct_uri: "acct:user@server.example",
|
||||
# alias_url: "https://server.example/people/0123456789abcdef",
|
||||
# hcard_url: "https://server.example/hcard/users/0123456789abcdef",
|
||||
# seed_url: "https://server.example/",
|
||||
# profile_url: "https://server.example/u/user",
|
||||
# atom_url: "https://server.example/public/user.atom",
|
||||
# salmon_url: "https://server.example/receive/users/0123456789abcdef",
|
||||
# guid: "0123456789abcdef",
|
||||
# pubkey: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----"
|
||||
# })
|
||||
# xml_string = wf.to_xml
|
||||
# @example Creating a WebFinger document from a person object
|
||||
# xml_string = WebFinger.from_person(person).to_xml
|
||||
#
|
||||
# The person object should have the following attributes (with examples)
|
||||
# diaspora_handle: "user@server.example"
|
||||
# alias_url: "https://server.example/people/0123456789abcdef"
|
||||
# hcard_url: "https://server.example/hcard/users/0123456789abcdef"
|
||||
# seed_url: "https://server.example/"
|
||||
# profile_url: "https://server.example/u/user"
|
||||
# atom_url: "https://server.example/public/user.atom"
|
||||
# salmon_url: "https://server.example/receive/users/0123456789abcdef"
|
||||
# guid: "0123456789abcdef"
|
||||
# public_key: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----"
|
||||
#
|
||||
# @example Creating a WebFinger instance from an xml document
|
||||
# wf = WebFinger.from_xml(xml_string)
|
||||
|
|
@ -89,7 +89,7 @@ module DiasporaFederation
|
|||
# DER-encoded PKCS#1 key beginning with the text
|
||||
# "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----".
|
||||
# @return [String] public key
|
||||
attr_reader :pubkey
|
||||
attr_reader :public_key
|
||||
|
||||
# +hcard_url+ link relation
|
||||
REL_HCARD = "http://microformats.org/profile/hcard"
|
||||
|
|
@ -131,26 +131,26 @@ module DiasporaFederation
|
|||
doc.to_xml
|
||||
end
|
||||
|
||||
# Create a WebFinger instance from the given person data Hash.
|
||||
# @param [Hash] data account data
|
||||
# Create a WebFinger instance from the given person.
|
||||
# @param [Person] person the person object
|
||||
# @return [WebFinger] WebFinger instance
|
||||
# @raise [InvalidData] if the given data Hash is invalid or incomplete
|
||||
def self.from_person(data)
|
||||
raise InvalidData, "person data incomplete" unless account_data_complete?(data)
|
||||
# @raise [ArgumentError] if the given person is nil
|
||||
def self.from_person(person)
|
||||
raise ArgumentError, "person is nil" if person.nil?
|
||||
|
||||
wf = allocate
|
||||
wf.instance_eval {
|
||||
@acct_uri = data[:acct_uri]
|
||||
@alias_url = data[:alias_url]
|
||||
@hcard_url = data[:hcard_url]
|
||||
@seed_url = data[:seed_url]
|
||||
@profile_url = data[:profile_url]
|
||||
@atom_url = data[:atom_url]
|
||||
@salmon_url = data[:salmon_url]
|
||||
@acct_uri = "acct:#{person.diaspora_handle}"
|
||||
@alias_url = person.alias_url
|
||||
@hcard_url = person.hcard_url
|
||||
@seed_url = person.seed_url
|
||||
@profile_url = person.profile_url
|
||||
@atom_url = person.atom_url
|
||||
@salmon_url = person.salmon_url
|
||||
|
||||
# TODO: remove me! #########
|
||||
@guid = data[:guid]
|
||||
@pubkey = data[:pubkey]
|
||||
@guid = person.guid
|
||||
@public_key = person.public_key
|
||||
#############################
|
||||
}
|
||||
wf
|
||||
|
|
@ -163,7 +163,7 @@ module DiasporaFederation
|
|||
def self.from_xml(webfinger_xml)
|
||||
data = parse_xml_and_validate(webfinger_xml)
|
||||
|
||||
hcard_url, seed_url, guid, profile_url, atom_url, salmon_url, pubkey = parse_links(data)
|
||||
hcard_url, seed_url, guid, profile_url, atom_url, salmon_url, public_key = parse_links(data)
|
||||
|
||||
wf = allocate
|
||||
wf.instance_eval {
|
||||
|
|
@ -177,7 +177,7 @@ module DiasporaFederation
|
|||
|
||||
# TODO: remove me! ##########
|
||||
@guid = guid
|
||||
@pubkey = Base64.strict_decode64(pubkey)
|
||||
@public_key = Base64.strict_decode64(public_key)
|
||||
##############################
|
||||
}
|
||||
wf
|
||||
|
|
@ -185,18 +185,6 @@ module DiasporaFederation
|
|||
|
||||
private
|
||||
|
||||
# Checks the given account data Hash for correct type and completeness.
|
||||
# @param [Hash] data account data
|
||||
# @return [Boolean] validation result
|
||||
def self.account_data_complete?(data)
|
||||
data.instance_of?(Hash) &&
|
||||
%i(
|
||||
acct_uri alias_url hcard_url seed_url
|
||||
guid profile_url atom_url salmon_url pubkey
|
||||
).all? {|k| data.key? k }
|
||||
end
|
||||
private_class_method :account_data_complete?
|
||||
|
||||
# Parses the XML string to a Hash and does some rudimentary checking on
|
||||
# the data Hash.
|
||||
# @param [String] webfinger_xml WebFinger XML string
|
||||
|
|
@ -236,7 +224,7 @@ module DiasporaFederation
|
|||
# TODO: remove me! ##############
|
||||
doc.links << {rel: REL_PUBKEY,
|
||||
type: "RSA",
|
||||
href: Base64.strict_encode64(@pubkey)}
|
||||
href: Base64.strict_encode64(@public_key)}
|
||||
##################################
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ module DiasporaFederation
|
|||
end
|
||||
|
||||
it "calls WebFinger::WebFinger.from_person" do
|
||||
expect(WebFinger::WebFinger).to receive(:from_person).with(alice.webfinger_hash).and_call_original
|
||||
expect(WebFinger::WebFinger).to receive(:from_person).with(alice).and_call_original
|
||||
get :legacy_webfinger, "q" => "acct:alice@localhost:3000"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,29 +1,22 @@
|
|||
module DiasporaFederation
|
||||
describe WebFinger::WebFinger do
|
||||
let(:acct) { "acct:user@pod.example.tld" }
|
||||
let(:alias_url) { "http://pod.example.tld/" }
|
||||
let(:hcard_url) { "https://pod.example.tld/hcard/users/abcdef0123456789" }
|
||||
let(:seed_url) { "https://pod.geraspora.de/" }
|
||||
let(:guid) { "abcdef0123456789" }
|
||||
let(:profile_url) { "https://pod.example.tld/u/user" }
|
||||
let(:atom_url) { "https://pod.example.tld/public/user.atom" }
|
||||
let(:salmon_url) { "https://pod.example.tld/receive/users/abcdef0123456789" }
|
||||
let(:pubkey) { "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----" }
|
||||
let(:pubkey_base64) { Base64.strict_encode64(pubkey) }
|
||||
let(:person) { FactoryGirl.create(:person) }
|
||||
let(:acct) { "acct:#{person.diaspora_handle}" }
|
||||
let(:public_key_base64) { Base64.strict_encode64(person.public_key) }
|
||||
|
||||
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>#{alias_url}</Alias>
|
||||
<Link rel="http://microformats.org/profile/hcard" type="text/html" href="#{hcard_url}"/>
|
||||
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="#{seed_url}"/>
|
||||
<Link rel="http://joindiaspora.com/guid" type="text/html" href="#{guid}"/>
|
||||
<Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="#{profile_url}"/>
|
||||
<Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="#{atom_url}"/>
|
||||
<Link rel="salmon" href="#{salmon_url}"/>
|
||||
<Link rel="diaspora-public-key" type="RSA" href="#{pubkey_base64}"/>
|
||||
<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.seed_url}"/>
|
||||
<Link rel="http://joindiaspora.com/guid" type="text/html" href="#{person.guid}"/>
|
||||
<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="diaspora-public-key" type="RSA" href="#{public_key_base64}"/>
|
||||
</XRD>
|
||||
XML
|
||||
}
|
||||
|
|
@ -34,36 +27,12 @@ XML
|
|||
|
||||
context "generation" do
|
||||
it "creates a nice XML document" do
|
||||
wf = WebFinger::WebFinger.from_person(
|
||||
acct_uri: acct,
|
||||
alias_url: alias_url,
|
||||
hcard_url: hcard_url,
|
||||
seed_url: seed_url,
|
||||
profile_url: profile_url,
|
||||
atom_url: atom_url,
|
||||
salmon_url: salmon_url,
|
||||
guid: guid,
|
||||
pubkey: pubkey
|
||||
)
|
||||
wf = WebFinger::WebFinger.from_person(person)
|
||||
expect(wf.to_xml).to eq(xml)
|
||||
end
|
||||
|
||||
it "fails if some params are missing" do
|
||||
expect {
|
||||
WebFinger::WebFinger.from_person(
|
||||
acct_uri: acct,
|
||||
alias_url: alias_url,
|
||||
hcard_url: hcard_url
|
||||
)
|
||||
}.to raise_error(WebFinger::InvalidData)
|
||||
end
|
||||
|
||||
it "fails if empty was given" do
|
||||
expect { WebFinger::WebFinger.from_person({}) }.to raise_error WebFinger::InvalidData
|
||||
end
|
||||
|
||||
it "fails if nil was given" do
|
||||
expect { WebFinger::WebFinger.from_person(nil) }.to raise_error WebFinger::InvalidData
|
||||
expect { WebFinger::WebFinger.from_person(nil) }.to raise_error ArgumentError
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -71,15 +40,15 @@ XML
|
|||
it "reads its own output" do
|
||||
wf = WebFinger::WebFinger.from_xml(xml)
|
||||
expect(wf.acct_uri).to eq(acct)
|
||||
expect(wf.alias_url).to eq(alias_url)
|
||||
expect(wf.hcard_url).to eq(hcard_url)
|
||||
expect(wf.seed_url).to eq(seed_url)
|
||||
expect(wf.profile_url).to eq(profile_url)
|
||||
expect(wf.atom_url).to eq(atom_url)
|
||||
expect(wf.salmon_url).to eq(salmon_url)
|
||||
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.seed_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.guid).to eq(guid)
|
||||
expect(wf.pubkey).to eq(pubkey)
|
||||
expect(wf.guid).to eq(person.guid)
|
||||
expect(wf.public_key).to eq(person.public_key)
|
||||
end
|
||||
|
||||
it "reads old-style XML" do
|
||||
|
|
@ -87,30 +56,30 @@ XML
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||
<Subject>#{acct}</Subject>
|
||||
<Alias>#{alias_url}</Alias>
|
||||
<Link rel="http://microformats.org/profile/hcard" type="text/html" href="#{hcard_url}"/>
|
||||
<Link rel="http://joindiaspora.com/seed_location" type = "text/html" href="#{seed_url}"/>
|
||||
<Link rel="http://joindiaspora.com/guid" type = "text/html" href="#{guid}"/>
|
||||
<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.seed_url}"/>
|
||||
<Link rel="http://joindiaspora.com/guid" type = "text/html" href="#{person.guid}"/>
|
||||
|
||||
<Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="#{profile_url}"/>
|
||||
<Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="#{atom_url}"/>
|
||||
<Link rel="salmon" href="#{salmon_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="diaspora-public-key" type = "RSA" href="#{pubkey_base64}"/>
|
||||
<Link rel="diaspora-public-key" type = "RSA" href="#{public_key_base64}"/>
|
||||
</XRD>
|
||||
XML
|
||||
|
||||
wf = WebFinger::WebFinger.from_xml(historic_xml)
|
||||
expect(wf.acct_uri).to eq(acct)
|
||||
expect(wf.alias_url).to eq(alias_url)
|
||||
expect(wf.hcard_url).to eq(hcard_url)
|
||||
expect(wf.seed_url).to eq(seed_url)
|
||||
expect(wf.profile_url).to eq(profile_url)
|
||||
expect(wf.atom_url).to eq(atom_url)
|
||||
expect(wf.salmon_url).to eq(salmon_url)
|
||||
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.seed_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.guid).to eq(guid)
|
||||
expect(wf.pubkey).to eq(pubkey)
|
||||
expect(wf.guid).to eq(person.guid)
|
||||
expect(wf.public_key).to eq(person.public_key)
|
||||
end
|
||||
|
||||
it "fails if the document is empty" do
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
class Person < ActiveRecord::Base
|
||||
include ::Diaspora::Guid
|
||||
|
||||
def webfinger_hash
|
||||
{
|
||||
acct_uri: "acct:#{diaspora_handle}",
|
||||
alias_url: "#{url}people/#{guid}",
|
||||
hcard_url: "#{url}hcard/users/#{guid}",
|
||||
seed_url: url,
|
||||
profile_url: "#{url}u/#{diaspora_handle.split('@')[0]}",
|
||||
atom_url: "#{url}public/#{diaspora_handle.split('@')[0]}.atom",
|
||||
salmon_url: "#{url}receive/users/#{guid}",
|
||||
guid: guid,
|
||||
pubkey: serialized_public_key
|
||||
}
|
||||
end
|
||||
def alias_url; "#{url}people/#{guid}" end
|
||||
def hcard_url; "#{url}hcard/users/#{guid}" end
|
||||
def profile_url; "#{url}u/#{diaspora_handle.split('@')[0]}" end
|
||||
def atom_url; "#{url}public/#{diaspora_handle.split('@')[0]}.atom" end
|
||||
def salmon_url; "#{url}receive/users/#{guid}" end
|
||||
|
||||
alias_attribute :seed_url, :url
|
||||
alias_attribute :public_key, :serialized_public_key
|
||||
|
||||
def hcard_profile_hash
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue