about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorEugen <eugen@zeonfederated.com>2017-04-25 02:47:31 +0200
committerGitHub <noreply@github.com>2017-04-25 02:47:31 +0200
commit17c591ffba59bda512fe43a09c06c40324acc472 (patch)
treec03ba1c23b0adf46230b3b97b62efb018c26ded5 /app/models
parentbb04a9be52e005fb8bbeef22e5b8d30f0d202903 (diff)
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
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb31
-rw-r--r--app/models/domain_block.rb8
-rw-r--r--app/models/media_attachment.rb2
3 files changed, 29 insertions, 12 deletions
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