about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-08-07 21:14:08 +0200
committerGitHub <noreply@github.com>2019-08-07 21:14:08 +0200
commitf51c7c105f1d04520656c1235f8a5f58d256fd0e (patch)
tree5e80a460c637b71daa7ab81f6bf7c6afde1ad5e5
parent3a6b6c63f22e31c9b113428d6c69be451a3bcc17 (diff)
Fix acct URIs with IDN domains not being resolved (#11520)
Fix #11494
-rw-r--r--app/controllers/remote_interaction_controller.rb1
-rw-r--r--app/models/remote_follow.rb36
-rw-r--r--app/services/resolve_account_service.rb14
3 files changed, 40 insertions, 11 deletions
diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb
index fa742fb0a..de5616e25 100644
--- a/app/controllers/remote_interaction_controller.rb
+++ b/app/controllers/remote_interaction_controller.rb
@@ -39,7 +39,6 @@ class RemoteInteractionController < ApplicationController
     @status = Status.find(params[:id])
     authorize @status, :show?
   rescue Mastodon::NotPermittedError
-    # Reraise in order to get a 404
     raise ActiveRecord::RecordNotFound
   end
 
diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb
index 2537de36c..93df11724 100644
--- a/app/models/remote_follow.rb
+++ b/app/models/remote_follow.rb
@@ -2,19 +2,21 @@
 
 class RemoteFollow
   include ActiveModel::Validations
+  include RoutingHelper
 
   attr_accessor :acct, :addressable_template
 
   validates :acct, presence: true
 
-  def initialize(attrs = nil)
-    @acct = attrs[:acct].gsub(/\A@/, '').strip if !attrs.nil? && !attrs[:acct].nil?
+  def initialize(attrs = {})
+    @acct = normalize_acct(attrs[:acct])
   end
 
   def valid?
     return false unless super
 
-    populate_template
+    fetch_template!
+
     errors.empty?
   end
 
@@ -28,8 +30,30 @@ class RemoteFollow
 
   private
 
-  def populate_template
-    if acct.blank? || redirect_url_link.nil? || redirect_url_link.template.nil?
+  def normalize_acct(value)
+    return if value.blank?
+
+    username, domain = value.strip.gsub(/\A@/, '').split('@')
+
+    domain = begin
+      if TagManager.instance.local_domain?(domain)
+        nil
+      else
+        TagManager.instance.normalize_domain(domain)
+      end
+    end
+
+    [username, domain].compact.join('@')
+  end
+
+  def fetch_template!
+    return missing_resource if acct.blank?
+
+    _, domain = acct.split('@')
+
+    if domain.nil?
+      @addressable_template = Addressable::Template.new("#{authorize_interaction_url}?uri={uri}")
+    elsif redirect_url_link.nil? || redirect_url_link.template.nil?
       missing_resource_error
     else
       @addressable_template = Addressable::Template.new(redirect_uri_template)
@@ -45,7 +69,7 @@ class RemoteFollow
   end
 
   def acct_resource
-    @_acct_resource ||= Goldfinger.finger("acct:#{acct}")
+    @acct_resource ||= Goldfinger.finger("acct:#{acct}")
   rescue Goldfinger::Error, HTTP::ConnectionError
     nil
   end
diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb
index 7864c4bcd..12e6544a0 100644
--- a/app/services/resolve_account_service.rb
+++ b/app/services/resolve_account_service.rb
@@ -60,17 +60,23 @@ class ResolveAccountService < BaseService
       @account  = uri
       @username = @account.username
       @domain   = @account.domain
-      @uri      = [@username, @domain].compact.join('@')
     else
-      @uri               = uri
       @username, @domain = uri.split('@')
     end
 
-    @domain = nil if TagManager.instance.local_domain?(@domain)
+    @domain = begin
+      if TagManager.instance.local_domain?(@domain)
+        nil
+      else
+        TagManager.instance.normalize_domain(@domain)
+      end
+    end
+
+    @uri = [@username, @domain].compact.join('@')
   end
 
   def process_webfinger!(uri, redirected = false)
-    @webfinger                           = Goldfinger.finger("acct:#{@uri}")
+    @webfinger                           = Goldfinger.finger("acct:#{uri}")
     confirmed_username, confirmed_domain = @webfinger.subject.gsub(/\Aacct:/, '').split('@')
 
     if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?