Newer
Older
require File.join(Rails.root, 'lib/hcard')
require File.join(Rails.root, 'lib/webfinger_profile')
class Webfinger
class WebfingerFailedError < RuntimeError; end
def initialize(account)
@account = account.strip.gsub('acct:','').to_s.downcase
Raphael
a validé
@ssl = true
Rails.logger.info("event=webfinger status=initialized target=#{account}")
Raphael
a validé
end
Raphael
a validé
begin
person = Person.by_account_identifier(@account)
if person
MrZYX
a validé
if person.profile
Rails.logger.info("event=webfinger status=success route=local target=#{@account}")
return person
end
Raphael
a validé
webfinger_profile = get_webfinger_profile(profile_url)
MrZYX
a validé
if person
person.assign_new_profile_from_hcard(get_hcard(webfinger_profile))
fingered_person = person
else
fingered_person = make_person_from_webfinger(webfinger_profile)
end
if fingered_person
Rails.logger.info("event=webfinger status=success route=remote target=#{@account}")
fingered_person
else
Rails.logger.info("event=webfinger status=failure route=remote target=#{@account}")
raise WebfingerFailedError.new(@account)
end
Raphael
a validé
rescue Exception => e
Rails.logger.info("event=receive status=abort recipient=#{@account} reason='#{e.message}'")
end
end
private
def get_xrd
begin
profile_url = webfinger_profile_url(http.body)
if profile_url
return profile_url
else
raise "no profile URL"
end
rescue Exception => e
if @ssl
@ssl = false
retry
else
raise e
raise I18n.t('webfinger.xrd_fetch_failed', :account => @account)
end
Raphael
a validé
end
end
def get_webfinger_profile(profile_url)
begin
Raphael
a validé
rescue
raise I18n.t('webfinger.fetch_failed', :profile_url => profile_url)
end
return http.body
end
def hcard_url
@wf_profile.hcard
end
MrZYX
a validé
def get_hcard(webfinger_profile)
unless webfinger_profile.strip == ""
@wf_profile = WebfingerProfile.new(@account, webfinger_profile)
rescue
return I18n.t('webfinger.hcard_fetch_failed', :account => @account)
end
MrZYX
a validé
HCard.build hcard.body
else
nil
end
end
def make_person_from_webfinger(webfinger_profile)
card = get_hcard(webfinger_profile)
Person.create_from_webfinger(@wf_profile, card)
end
end
##helpers
private
def webfinger_profile_url(xrd_response)
Raphael
a validé
doc = Nokogiri::XML::Document.parse(xrd_response)
return nil if doc.namespaces["xmlns"] != "http://docs.oasis-open.org/ns/xri/xrd-1.0"
swizzle doc.at('Link[rel=lrdd]').attribute('template').value
end
def xrd_url
domain = @account.split('@')[1]
"http#{'s' if @ssl}://#{domain}/.well-known/host-meta"
end
def swizzle(template)
template.gsub '{uri}', @account
end
end