Fix uncaught domain normalization error in remote follow (#11703)

master
Eugen Rochko 5 years ago committed by GitHub
parent 6914482d0a
commit b54b725d6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/controllers/remote_follow_controller.rb
  2. 2
      app/controllers/remote_interaction_controller.rb
  3. 6
      app/models/remote_follow.rb
  4. 12
      app/validators/domain_validator.rb
  5. 4
      spec/controllers/remote_follow_controller_spec.rb
  6. 2
      spec/models/remote_follow_spec.rb

@ -29,7 +29,7 @@ class RemoteFollowController < ApplicationController
end end
def session_params def session_params
{ acct: session[:remote_follow] } { acct: session[:remote_follow] || current_account&.username }
end end
def set_body_classes def set_body_classes

@ -32,7 +32,7 @@ class RemoteInteractionController < ApplicationController
end end
def session_params def session_params
{ acct: session[:remote_follow] } { acct: session[:remote_follow] || current_account&.username }
end end
def set_status def set_status

@ -6,7 +6,7 @@ class RemoteFollow
attr_accessor :acct, :addressable_template attr_accessor :acct, :addressable_template
validates :acct, presence: true validates :acct, presence: true, domain: { acct: true }
def initialize(attrs = {}) def initialize(attrs = {})
@acct = normalize_acct(attrs[:acct]) @acct = normalize_acct(attrs[:acct])
@ -21,7 +21,7 @@ class RemoteFollow
end end
def subscribe_address_for(account) def subscribe_address_for(account)
addressable_template.expand(uri: account.local_username_and_domain).to_s addressable_template.expand(uri: ActivityPub::TagManager.instance.uri_for(account)).to_s
end end
def interact_address_for(status) def interact_address_for(status)
@ -44,6 +44,8 @@ class RemoteFollow
end end
[username, domain].compact.join('@') [username, domain].compact.join('@')
rescue Addressable::URI::InvalidURIError
value
end end
def fetch_template! def fetch_template!

@ -4,14 +4,22 @@ class DomainValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
return if value.blank? return if value.blank?
record.errors.add(attribute, I18n.t('domain_validator.invalid_domain')) unless compliant?(value) domain = begin
if options[:acct]
value.split('@').last
else
value
end
end
record.errors.add(attribute, I18n.t('domain_validator.invalid_domain')) unless compliant?(domain)
end end
private private
def compliant?(value) def compliant?(value)
Addressable::URI.new.tap { |uri| uri.host = value } Addressable::URI.new.tap { |uri| uri.host = value }
rescue Addressable::URI::InvalidURIError rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
false false
end end
end end

@ -66,9 +66,7 @@ describe RemoteFollowController do
end end
it 'redirects to the remote location' do it 'redirects to the remote location' do
address = "http://example.com/follow_me?acct=test_user%40#{Rails.configuration.x.local_domain}" expect(response).to redirect_to("http://example.com/follow_me?acct=https%3A%2F%2F#{Rails.configuration.x.local_domain}%2Fusers%2Ftest_user")
expect(response).to redirect_to(address)
end end
end end
end end

@ -61,7 +61,7 @@ RSpec.describe RemoteFollow do
subject { remote_follow.subscribe_address_for(account) } subject { remote_follow.subscribe_address_for(account) }
it 'returns subscribe address' do it 'returns subscribe address' do
is_expected.to eq 'https://quitter.no/main/ostatussub?profile=alice%40cb6e6126.ngrok.io' is_expected.to eq 'https://quitter.no/main/ostatussub?profile=https%3A%2F%2Fcb6e6126.ngrok.io%2Fusers%2Falice'
end end
end end
end end

Loading…
Cancel
Save