refactor WebFinger to use the PropertiesDSL
This commit is contained in:
parent
e955ef8966
commit
2c50d34370
7 changed files with 110 additions and 104 deletions
|
|
@ -33,12 +33,12 @@ module DiasporaFederation
|
|||
# </XRD>
|
||||
# GET /webfinger?q=<uri>
|
||||
def legacy_webfinger
|
||||
person = find_person(params[:q]) if params[:q]
|
||||
person_wf = find_person_webfinger(params[:q]) if params[:q]
|
||||
|
||||
return render nothing: true, status: 404 if person.nil?
|
||||
return render nothing: true, status: 404 if person_wf.nil?
|
||||
|
||||
logger.info "webfinger profile request for: #{person.diaspora_handle}"
|
||||
render body: WebFinger::WebFinger.from_person(person).to_xml, content_type: "application/xrd+xml"
|
||||
logger.info "webfinger profile request for: #{person_wf.acct_uri}"
|
||||
render body: person_wf.to_xml, content_type: "application/xrd+xml"
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -49,8 +49,8 @@ module DiasporaFederation
|
|||
@host_meta_xml ||= WebFinger::HostMeta.from_base_url(DiasporaFederation.server_uri.to_s).to_xml
|
||||
end
|
||||
|
||||
def find_person(query)
|
||||
DiasporaFederation.person_class.find_local_by_diaspora_handle(query.strip.downcase.gsub("acct:", ""))
|
||||
def find_person_webfinger(query)
|
||||
DiasporaFederation.callbacks.trigger(:person_webfinger_fetch, query.strip.downcase.gsub("acct:", ""))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,19 +8,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 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"
|
||||
# serialized_public_key: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----"
|
||||
# @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",
|
||||
# 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-----"
|
||||
# )
|
||||
# xml_string = wf.to_xml
|
||||
#
|
||||
# @example Creating a WebFinger instance from an xml document
|
||||
# wf = WebFinger.from_xml(xml_string)
|
||||
|
|
@ -33,62 +33,72 @@ module DiasporaFederation
|
|||
# @see http://code.google.com/p/webfinger/wiki/CommonLinkRelations
|
||||
# @see http://www.iana.org/assignments/link-relations/link-relations.xhtml
|
||||
# official list of IANA link relations
|
||||
class WebFinger
|
||||
private_class_method :new
|
||||
class WebFinger < Entity
|
||||
# @!attribute [r] acct_uri
|
||||
# The Subject element should contain the webfinger address that was asked
|
||||
# for. If it does not, then this webfinger profile MUST be ignored.
|
||||
# @return [String]
|
||||
property :acct_uri
|
||||
|
||||
# The Subject element should contain the webfinger address that was asked
|
||||
# for. If it does not, then this webfinger profile MUST be ignored.
|
||||
# @return [String]
|
||||
attr_reader :acct_uri
|
||||
# @!attribute [r] alias_url
|
||||
# @return [String] link to the users profile
|
||||
property :alias_url
|
||||
|
||||
# @return [String] link to the users profile
|
||||
attr_reader :alias_url, :profile_url
|
||||
# @!attribute [r] hcard_url
|
||||
# @return [String] link to the +hCard+
|
||||
property :hcard_url
|
||||
|
||||
# @return [String] link to the +hCard+
|
||||
attr_reader :hcard_url
|
||||
# @!attribute [r] seed_url
|
||||
# @return [String] link to the pod
|
||||
property :seed_url
|
||||
|
||||
# @return [String] link to the pod
|
||||
attr_reader :seed_url
|
||||
# @!attribute [r] profile_url
|
||||
# @return [String] link to the users profile
|
||||
property :profile_url
|
||||
|
||||
# This atom feed is an Activity Stream of the user's public posts. Diaspora
|
||||
# pods SHOULD publish an Activity Stream of public posts, but there is
|
||||
# currently no requirement to be able to read Activity Streams.
|
||||
# @see http://activitystrea.ms/ Activity Streams specification
|
||||
# @!attribute [r] atom_url
|
||||
# This atom feed is an Activity Stream of the user's public posts. Diaspora
|
||||
# pods SHOULD publish an Activity Stream of public posts, but there is
|
||||
# currently no requirement to be able to read Activity Streams.
|
||||
# @see http://activitystrea.ms/ Activity Streams specification
|
||||
#
|
||||
# Note that this feed MAY also be made available through the PubSubHubbub
|
||||
# mechanism by supplying a <link rel="hub"> in the atom feed itself.
|
||||
# @return [String] atom feed url
|
||||
attr_reader :atom_url
|
||||
# Note that this feed MAY also be made available through the PubSubHubbub
|
||||
# mechanism by supplying a <link rel="hub"> in the atom feed itself.
|
||||
# @return [String] atom feed url
|
||||
property :atom_url
|
||||
|
||||
# @return [String] salmon endpoint url
|
||||
# @see http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-salmon-00.html#SMLR
|
||||
# Panzer draft for Salmon, paragraph 3.3
|
||||
attr_reader :salmon_url
|
||||
# @!attribute [r] salmon_url
|
||||
# @return [String] salmon endpoint url
|
||||
# @see http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-salmon-00.html#SMLR
|
||||
# Panzer draft for Salmon, paragraph 3.3
|
||||
property :salmon_url
|
||||
|
||||
# @deprecated Either convert these to +Property+ elements or move to the
|
||||
# +hCard+, which actually has fields for an +UID+ defined in the +vCard+
|
||||
# specification (will affect older Diaspora* installations).
|
||||
# @!attribute [r] guid
|
||||
# @deprecated Either convert these to +Property+ elements or move to the
|
||||
# +hCard+, which actually has fields for an +UID+ defined in the +vCard+
|
||||
# specification (will affect older Diaspora* installations).
|
||||
#
|
||||
# @see HCard#guid
|
||||
# @see HCard#guid
|
||||
#
|
||||
# This is just the guid. When a user creates an account on a pod, the pod
|
||||
# MUST assign them a guid - a random hexadecimal string of at least 8
|
||||
# hexadecimal digits.
|
||||
# @return [String] guid
|
||||
attr_reader :guid
|
||||
# This is just the guid. When a user creates an account on a pod, the pod
|
||||
# MUST assign them a guid - a random hexadecimal string of at least 8
|
||||
# hexadecimal digits.
|
||||
# @return [String] guid
|
||||
property :guid
|
||||
|
||||
# @deprecated Either convert these to +Property+ elements or move to the
|
||||
# +hCard+, which actually has fields for an +KEY+ defined in the +vCard+
|
||||
# specification (will affect older Diaspora* installations).
|
||||
# @!attribute [r] public_key
|
||||
# @deprecated Either convert these to +Property+ elements or move to the
|
||||
# +hCard+, which actually has fields for an +KEY+ defined in the +vCard+
|
||||
# specification (will affect older Diaspora* installations).
|
||||
#
|
||||
# @see HCard#pubkey
|
||||
# @see HCard#pubkey
|
||||
#
|
||||
# When a user is created on the pod, the pod MUST generate a pgp keypair
|
||||
# for them. This key is used for signing messages. The format is a
|
||||
# DER-encoded PKCS#1 key beginning with the text
|
||||
# "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----".
|
||||
# @return [String] public key
|
||||
attr_reader :public_key
|
||||
# When a user is created on the pod, the pod MUST generate a pgp keypair
|
||||
# for them. This key is used for signing messages. The format is a
|
||||
# DER-encoded PKCS#1 key beginning with the text
|
||||
# "-----BEGIN PUBLIC KEY-----" and ending with "-----END PUBLIC KEY-----".
|
||||
# @return [String] public key
|
||||
property :public_key
|
||||
|
||||
# +hcard_url+ link relation
|
||||
REL_HCARD = "http://microformats.org/profile/hcard"
|
||||
|
|
@ -130,31 +140,6 @@ module DiasporaFederation
|
|||
doc.to_xml
|
||||
end
|
||||
|
||||
# Create a WebFinger instance from the given person.
|
||||
# @param [Person] person the person object
|
||||
# @return [WebFinger] WebFinger instance
|
||||
# @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 = "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 = person.guid
|
||||
@public_key = person.serialized_public_key
|
||||
#############################
|
||||
}
|
||||
wf
|
||||
end
|
||||
|
||||
# Create a WebFinger instance from the given XML string.
|
||||
# @param [String] webfinger_xml WebFinger XML string
|
||||
# @return [WebFinger] WebFinger instance
|
||||
|
|
|
|||
|
|
@ -58,8 +58,10 @@ module DiasporaFederation
|
|||
expect(response).to be_not_found
|
||||
end
|
||||
|
||||
it "calls WebFinger::WebFinger.from_person" do
|
||||
expect(WebFinger::WebFinger).to receive(:from_person).with(alice).and_call_original
|
||||
it "calls the person_webfinger_fetch callback" do
|
||||
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||
.with(:person_webfinger_fetch, "alice@localhost:3000")
|
||||
.and_call_original
|
||||
get :legacy_webfinger, "q" => "acct:alice@localhost:3000"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module DiasporaFederation
|
|||
<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.seed_url}"/>
|
||||
<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="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}"/>
|
||||
|
|
@ -22,17 +22,27 @@ XML
|
|||
}
|
||||
|
||||
it "must not create blank instances" do
|
||||
expect { WebFinger::WebFinger.new }.to raise_error NameError
|
||||
expect { WebFinger::WebFinger.new({}) }.to raise_error ArgumentError
|
||||
end
|
||||
|
||||
context "generation" do
|
||||
it "creates a nice XML document" do
|
||||
wf = WebFinger::WebFinger.from_person(person)
|
||||
wf = WebFinger::WebFinger.new(
|
||||
acct_uri: "acct:#{person.diaspora_handle}",
|
||||
alias_url: person.alias_url,
|
||||
hcard_url: person.hcard_url,
|
||||
seed_url: person.url,
|
||||
profile_url: person.profile_url,
|
||||
atom_url: person.atom_url,
|
||||
salmon_url: person.salmon_url,
|
||||
guid: person.guid,
|
||||
public_key: person.serialized_public_key
|
||||
)
|
||||
expect(wf.to_xml).to eq(xml)
|
||||
end
|
||||
|
||||
it "fails if nil was given" do
|
||||
expect { WebFinger::WebFinger.from_person(nil) }.to raise_error ArgumentError
|
||||
expect { WebFinger::WebFinger.new(nil) }.to raise_error ArgumentError, "expected a Hash"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -42,7 +52,7 @@ 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.seed_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)
|
||||
|
|
@ -58,7 +68,7 @@ XML
|
|||
<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.seed_url}"/>
|
||||
<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="http://webfinger.net/rel/profile-page" type="text/html" href="#{person.profile_url}"/>
|
||||
|
|
@ -73,7 +83,7 @@ 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.seed_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)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ require "entities"
|
|||
# some helper methods
|
||||
|
||||
def alice
|
||||
@alice ||= Person.find_local_by_diaspora_handle("alice@localhost:3000")
|
||||
@alice ||= Person.find_by(diaspora_handle: "alice@localhost:3000")
|
||||
end
|
||||
|
||||
# Force fixture rebuild
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ class Person < ActiveRecord::Base
|
|||
def atom_url; "#{url}public/#{diaspora_handle.split('@')[0]}.atom" end
|
||||
def salmon_url; "#{url}receive/users/#{guid}" end
|
||||
|
||||
alias_attribute :seed_url, :url
|
||||
|
||||
def nickname; diaspora_handle.split("@")[0] end
|
||||
def photo_large_url; "#{url}assets/user/default.png" end
|
||||
def photo_medium_url; "#{url}assets/user/default.png" end
|
||||
|
|
@ -19,11 +17,6 @@ class Person < ActiveRecord::Base
|
|||
def first_name; "Dummy" end
|
||||
def last_name; "User" end
|
||||
|
||||
def self.find_local_by_diaspora_handle(identifier)
|
||||
# no remote? and closed_account? check ... this class is only for testing
|
||||
find_by_diaspora_handle(identifier)
|
||||
end
|
||||
|
||||
def self.find_local_by_guid(guid)
|
||||
# no remote? and closed_account? check ... this class is only for testing
|
||||
find_by_guid(guid)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
require "diaspora_federation/web_finger"
|
||||
|
||||
# configure the federation engine
|
||||
DiasporaFederation.configure do |config|
|
||||
# the pod url
|
||||
|
|
@ -5,6 +7,20 @@ DiasporaFederation.configure do |config|
|
|||
|
||||
config.define_callbacks do
|
||||
on :person_webfinger_fetch do |handle|
|
||||
person = Person.find_by(diaspora_handle: handle)
|
||||
if person
|
||||
DiasporaFederation::WebFinger::WebFinger.new(
|
||||
acct_uri: "acct:#{person.diaspora_handle}",
|
||||
alias_url: person.alias_url,
|
||||
hcard_url: person.hcard_url,
|
||||
seed_url: person.url,
|
||||
profile_url: person.profile_url,
|
||||
atom_url: person.atom_url,
|
||||
salmon_url: person.salmon_url,
|
||||
guid: person.guid,
|
||||
public_key: person.serialized_public_key
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
on :person_hcard_fetch do |guid|
|
||||
|
|
|
|||
Loading…
Reference in a new issue