about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-08-30 02:19:17 +0200
committerGitHub <noreply@github.com>2019-08-30 02:19:17 +0200
commitb54b725d6bc8dd0a4ab0fe0bf408193c1bae8106 (patch)
tree2e0f0477b75ad45866ec62db62be93d4b467856c
parent6914482d0a6e7e654e17e7f2aa2f6a2acde6c59a (diff)
Fix uncaught domain normalization error in remote follow (#11703)
-rw-r--r--app/controllers/remote_follow_controller.rb2
-rw-r--r--app/controllers/remote_interaction_controller.rb2
-rw-r--r--app/models/remote_follow.rb6
-rw-r--r--app/validators/domain_validator.rb12
-rw-r--r--spec/controllers/remote_follow_controller_spec.rb4
-rw-r--r--spec/models/remote_follow_spec.rb2
6 files changed, 18 insertions, 10 deletions
diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb
index 0fb71d335..ba963a7a0 100644
--- a/app/controllers/remote_follow_controller.rb
+++ b/app/controllers/remote_follow_controller.rb
@@ -29,7 +29,7 @@ class RemoteFollowController < ApplicationController
   end
 
   def session_params
-    { acct: session[:remote_follow] }
+    { acct: session[:remote_follow] || current_account&.username }
   end
 
   def set_body_classes
diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb
index de5616e25..15224e853 100644
--- a/app/controllers/remote_interaction_controller.rb
+++ b/app/controllers/remote_interaction_controller.rb
@@ -32,7 +32,7 @@ class RemoteInteractionController < ApplicationController
   end
 
   def session_params
-    { acct: session[:remote_follow] }
+    { acct: session[:remote_follow] || current_account&.username }
   end
 
   def set_status
diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb
index 93df11724..52dd3f67b 100644
--- a/app/models/remote_follow.rb
+++ b/app/models/remote_follow.rb
@@ -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])
@@ -21,7 +21,7 @@ class RemoteFollow
   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)
@@ -44,6 +44,8 @@ class RemoteFollow
     end
 
     [username, domain].compact.join('@')
+  rescue Addressable::URI::InvalidURIError
+    value
   end
 
   def fetch_template!
diff --git a/app/validators/domain_validator.rb b/app/validators/domain_validator.rb
index ae07f1798..6e4a854ff 100644
--- a/app/validators/domain_validator.rb
+++ b/app/validators/domain_validator.rb
@@ -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
diff --git a/spec/controllers/remote_follow_controller_spec.rb b/spec/controllers/remote_follow_controller_spec.rb
index 5088c2e65..d79dd2949 100644
--- a/spec/controllers/remote_follow_controller_spec.rb
+++ b/spec/controllers/remote_follow_controller_spec.rb
@@ -66,9 +66,7 @@ describe RemoteFollowController do
         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
diff --git a/spec/models/remote_follow_spec.rb b/spec/models/remote_follow_spec.rb
index ed2667b28..5b4c19b5b 100644
--- a/spec/models/remote_follow_spec.rb
+++ b/spec/models/remote_follow_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe RemoteFollow do
     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