Skip to content
Extraits de code Groupes Projets
webfinger.rb 2,99 ko
Newer Older
  • Learn to ignore specific revisions
  • 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
    
        Rails.logger.info("event=webfinger status=initialized target=#{account}")
    
    maxwell's avatar
    maxwell a validé
          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
    
    maxwell's avatar
    maxwell a validé
          end
    
    maxwell's avatar
    maxwell a validé
          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
    
    
    maxwell's avatar
    maxwell a validé
          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}'")
    
    maxwell's avatar
    maxwell a validé
          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
    
    
      def get_webfinger_profile(profile_url)
        begin
    
          http = Faraday.get(profile_url)
    
        rescue
          raise I18n.t('webfinger.fetch_failed', :profile_url => profile_url)
    
      def hcard_url
        @wf_profile.hcard
      end
    
    
        unless webfinger_profile.strip == ""
    
    
          @wf_profile = WebfingerProfile.new(@account, webfinger_profile)
    
            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