diaspora/lib/webfinger.rb

111 lines
2.7 KiB
Ruby

require File.join(Rails.root, 'lib/hcard')
require File.join(Rails.root, 'lib/webfinger_profile')
class Webfinger
attr_accessor :host_meta_xrd, :webfinger_profile_xrd,
:webfinger_profile, :hcard, :hcard_xrd, :person,
:account, :ssl
def initialize(account)
self.account = account
self.ssl = true
Rails.logger.info("event=webfinger status=initialized target=#{account}")
end
def fetch
return person if existing_person_with_profile?
create_or_update_person_from_webfinger_profile!
end
def self.in_background(account, opts={})
Resque.enqueue(Jobs::FetchWebfinger, account)
end
#everything below should be private I guess
def account=(str)
@account = str.strip.gsub('acct:','').to_s.downcase
end
def get(url)
Rails.logger.info("Getting: #{url} for #{account}")
begin
Faraday.get(url).body
rescue Exception => e
Rails.logger.info("Failed to fetch: #{url} for #{account}; #{e.message}")
raise e
end
end
def existing_person_with_profile?
cached_person.present? && cached_person.profile.present?
end
def cached_person
self.person ||= Person.by_account_identifier(account)
end
def create_or_update_person_from_webfinger_profile!
if person #update my profile please
person.assign_new_profile_from_hcard(self.hcard)
else
person = make_person_from_webfinger
end
Rails.logger.info("event=webfinger status=success route=remote target=#{@account}")
person
end
#this tries the xrl url with https first, then falls back to http
def host_meta_xrd
begin
get(host_meta_url)
rescue Exception => e
if self.ssl
self.ssl = false
retry
else
raise I18n.t('webfinger.xrd_fetch_failed', :account => account)
end
end
end
def hcard
@hcard ||= HCard.build(hcard_xrd)
end
def webfinger_profile
@webfinger_profile ||= WebfingerProfile.new(account, webfinger_profile_xrd)
end
def hcard_url
self.webfinger_profile.hcard
end
def webfinger_profile_url
doc = Nokogiri::XML::Document.parse(self.host_meta_xrd)
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 webfinger_profile_xrd
@webfinger_profile_xrd ||= get(webfinger_profile_url)
end
def hcard_xrd
@hcard_xrd ||= get(hcard_url)
end
def make_person_from_webfinger
Person.create_from_webfinger(webfinger_profile, hcard)
end
def host_meta_url
domain = account.split('@')[1]
"http#{'s' if self.ssl}://#{domain}/.well-known/host-meta"
end
def swizzle(template)
template.gsub('{uri}', account)
end
end