Refactor monkey-patching of Goldfinger (#12561)
This commit is contained in:
parent
4a2ea2e51b
commit
4b766f9846
6 changed files with 40 additions and 20 deletions
19
app/helpers/webfinger_helper.rb
Normal file
19
app/helpers/webfinger_helper.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module WebfingerHelper
|
||||||
|
def webfinger!(uri)
|
||||||
|
hidden_service_uri = /\.(onion|i2p)(:\d+)?$/.match(uri)
|
||||||
|
|
||||||
|
raise Mastodon::HostValidationError, 'Instance does not support hidden service connections' if !Rails.configuration.x.access_to_hidden_service && hidden_service_uri
|
||||||
|
|
||||||
|
opts = {
|
||||||
|
ssl: !hidden_service_uri,
|
||||||
|
|
||||||
|
headers: {
|
||||||
|
'User-Agent': Mastodon::Version.user_agent,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Goldfinger::Client.new(uri, opts.merge(Rails.configuration.x.http_client_proxy)).finger
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,6 +3,7 @@
|
||||||
class RemoteFollow
|
class RemoteFollow
|
||||||
include ActiveModel::Validations
|
include ActiveModel::Validations
|
||||||
include RoutingHelper
|
include RoutingHelper
|
||||||
|
include WebfingerHelper
|
||||||
|
|
||||||
attr_accessor :acct, :addressable_template
|
attr_accessor :acct, :addressable_template
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ class RemoteFollow
|
||||||
end
|
end
|
||||||
|
|
||||||
def acct_resource
|
def acct_resource
|
||||||
@acct_resource ||= Goldfinger.finger("acct:#{acct}")
|
@acct_resource ||= webfinger!("acct:#{acct}")
|
||||||
rescue Goldfinger::Error, HTTP::ConnectionError
|
rescue Goldfinger::Error, HTTP::ConnectionError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
class ActivityPub::FetchRemoteAccountService < BaseService
|
class ActivityPub::FetchRemoteAccountService < BaseService
|
||||||
include JsonLdHelper
|
include JsonLdHelper
|
||||||
include DomainControlHelper
|
include DomainControlHelper
|
||||||
|
include WebfingerHelper
|
||||||
|
|
||||||
SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
|
SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
|
||||||
|
|
||||||
|
@ -35,12 +36,12 @@ class ActivityPub::FetchRemoteAccountService < BaseService
|
||||||
private
|
private
|
||||||
|
|
||||||
def verified_webfinger?
|
def verified_webfinger?
|
||||||
webfinger = Goldfinger.finger("acct:#{@username}@#{@domain}")
|
webfinger = webfinger!("acct:#{@username}@#{@domain}")
|
||||||
confirmed_username, confirmed_domain = split_acct(webfinger.subject)
|
confirmed_username, confirmed_domain = split_acct(webfinger.subject)
|
||||||
|
|
||||||
return webfinger.link('self')&.href == @uri if @username.casecmp(confirmed_username).zero? && @domain.casecmp(confirmed_domain).zero?
|
return webfinger.link('self')&.href == @uri if @username.casecmp(confirmed_username).zero? && @domain.casecmp(confirmed_domain).zero?
|
||||||
|
|
||||||
webfinger = Goldfinger.finger("acct:#{confirmed_username}@#{confirmed_domain}")
|
webfinger = webfinger!("acct:#{confirmed_username}@#{confirmed_domain}")
|
||||||
@username, @domain = split_acct(webfinger.subject)
|
@username, @domain = split_acct(webfinger.subject)
|
||||||
self_reference = webfinger.link('self')
|
self_reference = webfinger.link('self')
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
class ResolveAccountService < BaseService
|
class ResolveAccountService < BaseService
|
||||||
include JsonLdHelper
|
include JsonLdHelper
|
||||||
include DomainControlHelper
|
include DomainControlHelper
|
||||||
|
include WebfingerHelper
|
||||||
|
|
||||||
class WebfingerRedirectError < StandardError; end
|
class WebfingerRedirectError < StandardError; end
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ class ResolveAccountService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_webfinger!(uri, redirected = false)
|
def process_webfinger!(uri, redirected = false)
|
||||||
@webfinger = Goldfinger.finger("acct:#{uri}")
|
@webfinger = webfinger!("acct:#{uri}")
|
||||||
confirmed_username, confirmed_domain = @webfinger.subject.gsub(/\Aacct:/, '').split('@')
|
confirmed_username, confirmed_domain = @webfinger.subject.gsub(/\Aacct:/, '').split('@')
|
||||||
|
|
||||||
if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
|
if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
config.x.http_client_proxy = {}
|
config.x.http_client_proxy = {}
|
||||||
|
|
||||||
if ENV['http_proxy'].present?
|
if ENV['http_proxy'].present?
|
||||||
proxy = URI.parse(ENV['http_proxy'])
|
proxy = URI.parse(ENV['http_proxy'])
|
||||||
|
|
||||||
raise "Unsupported proxy type: #{proxy.scheme}" unless %w(http https).include? proxy.scheme
|
raise "Unsupported proxy type: #{proxy.scheme}" unless %w(http https).include? proxy.scheme
|
||||||
raise "No proxy host" unless proxy.host
|
raise "No proxy host" unless proxy.host
|
||||||
|
|
||||||
host = proxy.host
|
host = proxy.host
|
||||||
host = host[1...-1] if host[0] == '[' # for IPv6 address
|
host = host[1...-1] if host[0] == '[' # for IPv6 address
|
||||||
config.x.http_client_proxy[:proxy] = { proxy_address: host, proxy_port: proxy.port, proxy_username: proxy.user, proxy_password: proxy.password }.compact
|
|
||||||
|
config.x.http_client_proxy[:proxy] = {
|
||||||
|
proxy_address: host,
|
||||||
|
proxy_port: proxy.port,
|
||||||
|
proxy_username: proxy.user,
|
||||||
|
proxy_password: proxy.password,
|
||||||
|
}.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
config.x.access_to_hidden_service = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true'
|
config.x.access_to_hidden_service = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true'
|
||||||
end
|
end
|
||||||
|
|
||||||
module Goldfinger
|
|
||||||
def self.finger(uri, opts = {})
|
|
||||||
to_hidden = /\.(onion|i2p)(:\d+)?$/.match(uri)
|
|
||||||
raise Mastodon::HostValidationError, 'Instance does not support hidden service connections' if !Rails.configuration.x.access_to_hidden_service && to_hidden
|
|
||||||
opts = { ssl: !to_hidden, headers: {} }.merge(Rails.configuration.x.http_client_proxy).merge(opts)
|
|
||||||
opts[:headers]['User-Agent'] ||= Mastodon::Version.user_agent
|
|
||||||
Goldfinger::Client.new(uri, opts).finger
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ describe RemoteFollowController do
|
||||||
context 'when webfinger values are wrong' do
|
context 'when webfinger values are wrong' do
|
||||||
it 'renders new when redirect url is nil' do
|
it 'renders new when redirect url is nil' do
|
||||||
resource_with_nil_link = double(link: nil)
|
resource_with_nil_link = double(link: nil)
|
||||||
allow(Goldfinger).to receive(:finger).with('acct:user@example.com').and_return(resource_with_nil_link)
|
allow_any_instance_of(WebfingerHelper).to receive(:webfinger!).with('acct:user@example.com').and_return(resource_with_nil_link)
|
||||||
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
||||||
|
|
||||||
expect(response).to render_template(:new)
|
expect(response).to render_template(:new)
|
||||||
|
@ -45,7 +45,7 @@ describe RemoteFollowController do
|
||||||
it 'renders new when template is nil' do
|
it 'renders new when template is nil' do
|
||||||
link_with_nil_template = double(template: nil)
|
link_with_nil_template = double(template: nil)
|
||||||
resource_with_link = double(link: link_with_nil_template)
|
resource_with_link = double(link: link_with_nil_template)
|
||||||
allow(Goldfinger).to receive(:finger).with('acct:user@example.com').and_return(resource_with_link)
|
allow_any_instance_of(WebfingerHelper).to receive(:webfinger!).with('acct:user@example.com').and_return(resource_with_link)
|
||||||
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
||||||
|
|
||||||
expect(response).to render_template(:new)
|
expect(response).to render_template(:new)
|
||||||
|
@ -57,7 +57,7 @@ describe RemoteFollowController do
|
||||||
before do
|
before do
|
||||||
link_with_template = double(template: 'http://example.com/follow_me?acct={uri}')
|
link_with_template = double(template: 'http://example.com/follow_me?acct={uri}')
|
||||||
resource_with_link = double(link: link_with_template)
|
resource_with_link = double(link: link_with_template)
|
||||||
allow(Goldfinger).to receive(:finger).with('acct:user@example.com').and_return(resource_with_link)
|
allow_any_instance_of(WebfingerHelper).to receive(:webfinger!).with('acct:user@example.com').and_return(resource_with_link)
|
||||||
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ describe RemoteFollowController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders new with error when goldfinger fails' do
|
it 'renders new with error when goldfinger fails' do
|
||||||
allow(Goldfinger).to receive(:finger).with('acct:user@example.com').and_raise(Goldfinger::Error)
|
allow_any_instance_of(WebfingerHelper).to receive(:webfinger!).with('acct:user@example.com').and_raise(Goldfinger::Error)
|
||||||
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@example.com' } }
|
||||||
|
|
||||||
expect(response).to render_template(:new)
|
expect(response).to render_template(:new)
|
||||||
|
@ -87,7 +87,7 @@ describe RemoteFollowController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders new when occur HTTP::ConnectionError' do
|
it 'renders new when occur HTTP::ConnectionError' do
|
||||||
allow(Goldfinger).to receive(:finger).with('acct:user@unknown').and_raise(HTTP::ConnectionError)
|
allow_any_instance_of(WebfingerHelper).to receive(:webfinger!).with('acct:user@unknown').and_raise(HTTP::ConnectionError)
|
||||||
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@unknown' } }
|
post :create, params: { account_username: @account.to_param, remote_follow: { acct: 'user@unknown' } }
|
||||||
|
|
||||||
expect(response).to render_template(:new)
|
expect(response).to render_template(:new)
|
||||||
|
|
Loading…
Reference in a new issue