render json: { error: 'Record not found' }, status: 404
end
- rescue_from Goldfinger::Error do
- render json: { error: 'Remote account could not be resolved' }, status: 422
- end
-
- rescue_from HTTP::Error do
+ rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
render json: { error: 'Remote data could not be fetched' }, status: 503
end
class NotPermittedError < Error; end
class ValidationError < Error; end
class RaceConditionError < Error; end
+
+ class UnexpectedResponseError < Error
+ def initialize(response = nil)
+ @response = response
+ end
+
+ def to_s
+ "#{@response.uri} returned code #{@response.code}"
+ end
+ end
end
rescue Nokogiri::XML::XPath::SyntaxError
Rails.logger.debug 'Invalid XML or missing namespace'
nil
- rescue Goldfinger::NotFoundError, Goldfinger::Error
- Rails.logger.debug 'Exceptions related to Goldfinger occurs'
- nil
end
end
rescue Nokogiri::XML::XPath::SyntaxError
Rails.logger.debug 'Invalid XML or missing namespace'
nil
- rescue Goldfinger::NotFoundError, Goldfinger::Error
- Rails.logger.debug 'Exceptions related to Goldfinger occurs'
- nil
end
def confirmed_domain?(domain, account)
reflect_unblock!(account, target_account)
end
end
- rescue Goldfinger::Error, HTTP::Error, OStatus2::BadSalmonError, Mastodon::NotPermittedError
+ rescue HTTP::Error, OStatus2::BadSalmonError, Mastodon::NotPermittedError
nil
end
@webfinger = Goldfinger.finger("acct:#{uri}")
- raise Goldfinger::Error, 'Missing resource links' if links_missing?
-
confirmed_username, confirmed_domain = @webfinger.subject.gsub(/\Aacct:/, '').split('@')
if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
@username = confirmed_username
@domain = confirmed_domain
+ elsif redirected.nil?
+ return call("#{confirmed_username}@#{confirmed_domain}", update_profile, true)
else
- return call("#{confirmed_username}@#{confirmed_domain}", update_profile, true) if redirected.nil?
- raise Goldfinger::Error, 'Requested and returned acct URIs do not match'
+ Rails.logger.debug 'Requested and returned acct URIs do not match'
+ return
end
+ return if links_missing?
return Account.find_local(@username) if TagManager.instance.local_domain?(@domain)
RedisLock.acquire(lock_options) do |lock|
end
@account
+ rescue Goldfinger::Error => e
+ Rails.logger.debug "Webfinger query for #{uri} unsuccessful: #{e}"
+ nil
end
private
@webfinger.link('http://schemas.google.com/g/2010#updates-from').nil? ||
@webfinger.link('salmon').nil? ||
@webfinger.link('http://webfinger.net/rel/profile-page').nil? ||
- @webfinger.link('magic-public-key').nil?
+ @webfinger.link('magic-public-key').nil? ||
+ canonical_uri.nil? ||
+ hub_url.nil?
end
def webfinger_update_due?
author_uri = owner.at_xpath('./xmlns:uri') unless owner.nil?
end
- raise Goldfinger::Error, 'Author URI could not be found' if author_uri.nil?
-
- @canonical_uri = author_uri.content
+ @canonical_uri = author_uri.nil? ? nil : author_uri.content
end
def hub_url
return @hub_url if defined?(@hub_url)
- hubs = atom.xpath('//xmlns:link[@rel="hub"]')
-
- raise Goldfinger::Error, 'No PubSubHubbub hubs found' if hubs.empty? || hubs.first['href'].nil?
-
- @hub_url = hubs.first['href']
+ hubs = atom.xpath('//xmlns:link[@rel="hub"]')
+ @hub_url = hubs.empty? || hubs.first['href'].nil? ? nil : hubs.first['href']
end
def atom_body
response = Request.new(:get, atom_url).perform
- raise Goldfinger::Error, "Feed attempt failed for #{atom_url}: HTTP #{response.code}" unless response.code == 200
+ raise Mastodon::UnexpectedResponseError, response unless response.code == 200
@atom_body = response.to_s
end
delivery = build_request.perform
- raise "Delivery failed for #{target_account.salmon_url}: HTTP #{delivery.code}" unless delivery.code > 199 && delivery.code < 300
+ raise Mastodon::UnexpectedResponseError, delivery unless delivery.code > 199 && delivery.code < 300
end
private
else
# The response was either a 429 rate limit, or a 5xx error.
# We need to retry at a later time. Fail loudly!
- raise "Subscription attempt failed for #{@account.acct} (#{@account.hub_url}): HTTP #{@response.code}"
+ raise Mastodon::UnexpectedResponseError, @response
end
end
target_account = ResolveRemoteAccountService.new.call(row.first)
next if target_account.nil?
MuteService.new.call(from_account, target_account)
- rescue Goldfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError
+ rescue Mastodon::UnexpectedResponseError, HTTP::Error, OpenSSL::SSL::SSLError
next
end
end
target_account = ResolveRemoteAccountService.new.call(row.first)
next if target_account.nil?
BlockService.new.call(from_account, target_account)
- rescue Goldfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError
+ rescue Mastodon::UnexpectedResponseError, HTTP::Error, OpenSSL::SSL::SSLError
next
end
end
import_rows.each do |row|
begin
FollowService.new.call(from_account, row.first)
- rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, Goldfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError
+ rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound, Mastodon::UnexpectedResponseError, HTTP::Error, OpenSSL::SSL::SSLError
next
end
end
def process_delivery
payload_delivery
- raise "Delivery failed for #{subscription.callback_url}: HTTP #{payload_delivery.code}" unless response_successful?
+ raise Mastodon::UnexpectedResponseError, payload_delivery unless response_successful?
subscription.touch(:last_successful_delivery_at)
end
ActiveRecord::RecordInvalid => 422,
Mastodon::ValidationError => 422,
ActiveRecord::RecordNotFound => 404,
- Goldfinger::Error => 422,
+ Mastodon::UnexpectedResponseError => 503,
HTTP::Error => 503,
OpenSSL::SSL::SSLError => 503,
Mastodon::NotPermittedError => 403,
end
it 'raises error if no such user can be resolved via webfinger' do
- expect { subject.call('catsrgr8@quitter.no') }.to raise_error Goldfinger::Error
+ expect(subject.call('catsrgr8@quitter.no')).to be_nil
end
it 'raises error if the domain does not have webfinger' do
- expect { subject.call('catsrgr8@example.com') }.to raise_error Goldfinger::Error
+ expect(subject.call('catsrgr8@example.com')).to be_nil
end
it 'returns an already existing remote account' do
end
it 'prevents hijacking inexisting accounts' do
- expect { subject.call('hacker2@redirected.com') }.to raise_error Goldfinger::Error
+ expect(subject.call('hacker2@redirected.com')).to be_nil
end
it 'returns a new remote account' do
it 'fails loudly if PuSH hub is unavailable' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 503)
- expect { subject.call(account) }.to raise_error(/Subscription attempt failed/)
+ expect { subject.call(account) }.to raise_error Mastodon::UnexpectedResponseError
end
it 'fails loudly if rate limited' do
stub_request(:post, 'http://hub.example.com/').to_return(status: 429)
- expect { subject.call(account) }.to raise_error(/Subscription attempt failed/)
+ expect { subject.call(account) }.to raise_error Mastodon::UnexpectedResponseError
end
end
subscription = Fabricate(:subscription)
stub_request_to_respond_with(subscription, 500)
- expect { subject.perform(subscription.id, payload) }.to raise_error(/Delivery failed/)
+ expect { subject.perform(subscription.id, payload) }.to raise_error Mastodon::UnexpectedResponseError
end
it 'updates subscriptions when delivery succeeds' do