Skip to content

Commit

Permalink
Fix uncaught domain normalization error in remote follow (mastodon#11703
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Gargron authored and umonaca committed Aug 30, 2019
1 parent fceb276 commit 5f40c52
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 10 deletions.
2 changes: 1 addition & 1 deletion app/controllers/remote_follow_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def resource_params
end

def session_params
{ acct: session[:remote_follow] }
{ acct: session[:remote_follow] || current_account&.username }
end

def set_body_classes
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/remote_interaction_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def resource_params
end

def session_params
{ acct: session[:remote_follow] }
{ acct: session[:remote_follow] || current_account&.username }
end

def set_status
Expand Down
6 changes: 4 additions & 2 deletions app/models/remote_follow.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class RemoteFollow

attr_accessor :acct, :addressable_template

validates :acct, presence: true
validates :acct, presence: true, domain: { acct: true }

def initialize(attrs = {})
@acct = normalize_acct(attrs[:acct])
Expand All @@ -21,7 +21,7 @@ def valid?
end

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

def interact_address_for(status)
Expand All @@ -44,6 +44,8 @@ def normalize_acct(value)
end

[username, domain].compact.join('@')
rescue Addressable::URI::InvalidURIError
value
end

def fetch_template!
Expand Down
12 changes: 10 additions & 2 deletions app/validators/domain_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@ class DomainValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
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

private

def compliant?(value)
Addressable::URI.new.tap { |uri| uri.host = value }
rescue Addressable::URI::InvalidURIError
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
false
end
end
4 changes: 1 addition & 3 deletions spec/controllers/remote_follow_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@
end

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(address)
expect(response).to redirect_to("http://example.com/follow_me?acct=https%3A%2F%2F#{Rails.configuration.x.local_domain}%2Fusers%2Ftest_user")
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/models/remote_follow_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
subject { remote_follow.subscribe_address_for(account) }

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

0 comments on commit 5f40c52

Please sign in to comment.