mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-30 20:27:18 +00:00
d19ed18388
The goal of this change is to enhance Mastodon's handling of remote domains for which the APIs reside on a different host (see issue #1032). Indeed, when a remote user unknown to Mastodon is mentionned, only its profile URL (e.g. https://social.example.org/users/User) is known, and Mastodon has to build a @username@domain handle for it. To do so, Mastodon fetches the user's atom feed (e.g., https://social.example.org/users/User.atom) and uses its content to get the username part of the handle, and the URL's host part to build the domain (e.g., @User@social.example.org). This handle is then used for a Webfinger request. In the case where example.org serves the Webfinger info for @User@example.org and all feeds and APIs are hosted at social.example.org, Mastodon will still build @User@social.example.org and fail at resolving the account's details through Webfinger. This patch changes this behaviour by using the author's email address from the atom feed to build the handle. In Mastodon-generated atom feeds, the email address is always the handle it expects for federation.
46 lines
1.2 KiB
Ruby
46 lines
1.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class FetchRemoteAccountService < BaseService
|
|
def call(url, prefetched_body = nil)
|
|
if prefetched_body.nil?
|
|
atom_url, body = FetchAtomService.new.call(url)
|
|
else
|
|
atom_url = url
|
|
body = prefetched_body
|
|
end
|
|
|
|
return nil if atom_url.nil?
|
|
process_atom(atom_url, body)
|
|
end
|
|
|
|
private
|
|
|
|
def process_atom(url, body)
|
|
xml = Nokogiri::XML(body)
|
|
xml.encoding = 'utf-8'
|
|
|
|
email = xml.at_xpath('//xmlns:author/xmlns:email').try(:content)
|
|
if email.nil?
|
|
url_parts = Addressable::URI.parse(url)
|
|
username = xml.at_xpath('//xmlns:author/xmlns:name').try(:content)
|
|
domain = url_parts.host
|
|
else
|
|
username, domain = email.split('@')
|
|
end
|
|
|
|
return nil if username.nil? || domain.nil?
|
|
|
|
Rails.logger.debug "Going to webfinger #{username}@#{domain}"
|
|
|
|
account = FollowRemoteAccountService.new.call("#{username}@#{domain}")
|
|
UpdateRemoteProfileService.new.call(xml, account) unless account.nil?
|
|
account
|
|
rescue TypeError
|
|
Rails.logger.debug "Unparseable URL given: #{url}"
|
|
nil
|
|
rescue Nokogiri::XML::XPath::SyntaxError
|
|
Rails.logger.debug 'Invalid XML or missing namespace'
|
|
nil
|
|
end
|
|
end
|