Welcome to mirror list, hosted at ThFree Co, Russian Federation.

webfinger.rb « lib - github.com/diaspora/diaspora.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2b742afa461ce9673d8a849f82d14832277ea08e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
    @ssl = true
    Rails.logger.info("event=webfinger status=initialized target=#{account}")
  end

  def fetch
    begin
      person = Person.by_account_identifier(@account)
      if person
        if person.profile
          Rails.logger.info("event=webfinger status=success route=local target=#{@account}")
          return person
        end
      end

      profile_url = get_xrd
      webfinger_profile = get_webfinger_profile(profile_url)
      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
    rescue Exception => e
      Rails.logger.info("event=receive status=abort recipient=#{@account} reason='#{e.message}'")
      nil
    end
  end

  private
  def get_xrd
    begin
      http = Faraday.get xrd_url

      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
    end
  end


  def get_webfinger_profile(profile_url)
    begin
      http = Faraday.get(profile_url)

    rescue
      raise I18n.t('webfinger.fetch_failed', :profile_url => profile_url)
    end
    return http.body
  end

  def hcard_url
    @wf_profile.hcard
  end

  def get_hcard(webfinger_profile)
    unless webfinger_profile.strip == ""

      @wf_profile = WebfingerProfile.new(@account, webfinger_profile)

      begin
        hcard = Faraday.get(hcard_url)
      rescue
        return I18n.t('webfinger.hcard_fetch_failed', :account => @account)
      end

      HCard.build hcard.body
    else
      nil
    end
  end

  def make_person_from_webfinger(webfinger_profile)
    card = get_hcard(webfinger_profile)
    if card && @wf_profile
      Person.create_from_webfinger(@wf_profile, card)
    end
  end


  ##helpers
  private

  def webfinger_profile_url(xrd_response)
    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