From f51c7c105f1d04520656c1235f8a5f58d256fd0e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Aug 2019 21:14:08 +0200 Subject: [PATCH] Fix acct URIs with IDN domains not being resolved (#11520) Fix #11494 --- .../remote_interaction_controller.rb | 1 - app/models/remote_follow.rb | 36 +++++++++++++++---- app/services/resolve_account_service.rb | 14 +++++--- 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?