From 17c591ffba59bda512fe43a09c06c40324acc472 Mon Sep 17 00:00:00 2001 From: Eugen Date: Tue, 25 Apr 2017 02:47:31 +0200 Subject: Punycode URI normalization (#2370) * Fix #2119 - Whenever about to send a HTTP request, normalize the URI * Add test for IDN request in FetchLinkCardService * Perform IDN normalization on domains before they are stored in the DB --- app/models/account.rb | 31 ++++++++++++++++++++----------- app/models/domain_block.rb | 8 ++++++++ app/models/media_attachment.rb | 2 +- 3 files changed, 29 insertions(+), 12 deletions(-) (limited to 'app/models') diff --git a/app/models/account.rb b/app/models/account.rb index 084b17f43..eebcf90b8 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -182,22 +182,22 @@ class Account < ApplicationRecord end def avatar_remote_url=(url) - parsed_url = URI.parse(url) + parsed_url = Addressable::URI.parse(url).normalize return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[:avatar_remote_url] == url - self.avatar = parsed_url + self.avatar = URI.parse(parsed_url.to_s) self[:avatar_remote_url] = url rescue OpenURI::HTTPError => e Rails.logger.debug "Error fetching remote avatar: #{e}" end def header_remote_url=(url) - parsed_url = URI.parse(url) + parsed_url = Addressable::URI.parse(url).normalize return if !%w(http https).include?(parsed_url.scheme) || parsed_url.host.empty? || self[:header_remote_url] == url - self.header = parsed_url + self.header = URI.parse(parsed_url.to_s) self[:header_remote_url] = url rescue OpenURI::HTTPError => e Rails.logger.debug "Error fetching remote header: #{e}" @@ -331,16 +331,25 @@ class Account < ApplicationRecord end end - before_create do - if local? - keypair = OpenSSL::PKey::RSA.new(Rails.env.test? ? 1024 : 2048) - self.private_key = keypair.to_pem - self.public_key = keypair.public_key.to_pem - end - end + before_create :generate_keys + before_validation :normalize_domain private + def generate_keys + return unless local? + + keypair = OpenSSL::PKey::RSA.new(Rails.env.test? ? 1024 : 2048) + self.private_key = keypair.to_pem + self.public_key = keypair.public_key.to_pem + end + + def normalize_domain + return if local? + + self.domain = TagManager.instance.normalize_domain(domain) + end + def set_file_extensions unless avatar.blank? extension = Paperclip::Interpolations.content_type_extension(avatar, :original) diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb index baf5c3973..6c2ba70f7 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -13,4 +13,12 @@ class DomainBlock < ApplicationRecord def self.blocked?(domain) where(domain: domain, severity: :suspend).exists? end + + before_validation :normalize_domain + + private + + def normalize_domain + self.domain = TagManager.instance.normalize_domain(domain) + end end diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 181e01674..a43c76c77 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -42,7 +42,7 @@ class MediaAttachment < ApplicationRecord end def file_remote_url=(url) - self.file = URI.parse(url) + self.file = URI.parse(Addressable::URI.parse(url).normalize.to_s) end def to_param -- cgit