Fix acct URIs with IDN domains not being resolved (#11520)

Fix #11494
This commit is contained in:
Eugen Rochko 2019-08-07 21:14:08 +02:00 committed by GitHub
parent 3a6b6c63f2
commit f51c7c105f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 11 deletions

View file

@ -39,7 +39,6 @@ class RemoteInteractionController < ApplicationController
@status = Status.find(params[:id]) @status = Status.find(params[:id])
authorize @status, :show? authorize @status, :show?
rescue Mastodon::NotPermittedError rescue Mastodon::NotPermittedError
# Reraise in order to get a 404
raise ActiveRecord::RecordNotFound raise ActiveRecord::RecordNotFound
end end

View file

@ -2,19 +2,21 @@
class RemoteFollow class RemoteFollow
include ActiveModel::Validations include ActiveModel::Validations
include RoutingHelper
attr_accessor :acct, :addressable_template attr_accessor :acct, :addressable_template
validates :acct, presence: true validates :acct, presence: true
def initialize(attrs = nil) def initialize(attrs = {})
@acct = attrs[:acct].gsub(/\A@/, '').strip if !attrs.nil? && !attrs[:acct].nil? @acct = normalize_acct(attrs[:acct])
end end
def valid? def valid?
return false unless super return false unless super
populate_template fetch_template!
errors.empty? errors.empty?
end end
@ -28,8 +30,30 @@ class RemoteFollow
private private
def populate_template def normalize_acct(value)
if acct.blank? || redirect_url_link.nil? || redirect_url_link.template.nil? 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 missing_resource_error
else else
@addressable_template = Addressable::Template.new(redirect_uri_template) @addressable_template = Addressable::Template.new(redirect_uri_template)
@ -45,7 +69,7 @@ class RemoteFollow
end end
def acct_resource def acct_resource
@_acct_resource ||= Goldfinger.finger("acct:#{acct}") @acct_resource ||= Goldfinger.finger("acct:#{acct}")
rescue Goldfinger::Error, HTTP::ConnectionError rescue Goldfinger::Error, HTTP::ConnectionError
nil nil
end end

View file

@ -60,17 +60,23 @@ class ResolveAccountService < BaseService
@account = uri @account = uri
@username = @account.username @username = @account.username
@domain = @account.domain @domain = @account.domain
@uri = [@username, @domain].compact.join('@')
else else
@uri = uri
@username, @domain = uri.split('@') @username, @domain = uri.split('@')
end 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 end
def process_webfinger!(uri, redirected = false) 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('@') confirmed_username, confirmed_domain = @webfinger.subject.gsub(/\Aacct:/, '').split('@')
if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero? if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?