diff --git a/app/models/pod.rb b/app/models/pod.rb index ff61af5b3..0f3177c2b 100644 --- a/app/models/pod.rb +++ b/app/models/pod.rb @@ -58,7 +58,7 @@ class Pod < ApplicationRecord def find_or_create_by(opts) # Rename this method to not override an AR method uri = URI.parse(opts.fetch(:url)) port = DEFAULT_PORTS.include?(uri.port) ? DEFAULT_PORT : uri.port - find_or_initialize_by(host: uri.host, port: port).tap do |pod| + find_or_initialize_by(host: uri.host.downcase, port: port).tap do |pod| pod.ssl ||= (uri.scheme == "https") pod.save end @@ -168,6 +168,6 @@ class Pod < ApplicationRecord def not_own_pod pod_uri = AppConfig.pod_uri pod_port = DEFAULT_PORTS.include?(pod_uri.port) ? DEFAULT_PORT : pod_uri.port - errors.add(:base, "own pod not allowed") if pod_uri.host == host && pod_port == port + errors.add(:base, "own pod not allowed") if pod_uri.host.downcase == host && pod_port == port end end diff --git a/db/migrate/20221030193943_cleanup_duplicate_pods.rb b/db/migrate/20221030193943_cleanup_duplicate_pods.rb index fe1bc5fa2..18fd5740d 100644 --- a/db/migrate/20221030193943_cleanup_duplicate_pods.rb +++ b/db/migrate/20221030193943_cleanup_duplicate_pods.rb @@ -8,6 +8,7 @@ class CleanupDuplicatePods < ActiveRecord::Migration[6.1] reversible do |change| change.up do remove_duplicates + cleanup_mixed_case_pods Pod.where(port: nil).update_all(port: -1) # rubocop:disable Rails/SkipsModelValidations end @@ -24,13 +25,24 @@ class CleanupDuplicatePods < ActiveRecord::Migration[6.1] def remove_duplicates Pod.where(port: nil).group(:host).having("count(*) > 1").pluck(:host).each do |host| - duplicate_ids = Pod.where(host: host).order(:id).ids - target_pod_id = duplicate_ids.shift + cleanup_duplicates(Pod.where(host: host).order(:id).ids) + end + end - duplicate_ids.each do |pod_id| - Person.where(pod_id: pod_id).update_all(pod_id: target_pod_id) # rubocop:disable Rails/SkipsModelValidations - Pod.delete(pod_id) - end + def cleanup_mixed_case_pods + Pod.where("lower(host) != host").pluck(:host, :port).each do |host, port| + pod_ids = Pod.where("lower(host) = ?", host.downcase).where(port: port).order(:id).ids + cleanup_duplicates(pod_ids.dup) if pod_ids.size > 1 + Pod.find(pod_ids.first).update(host: host.downcase) + end + end + + def cleanup_duplicates(duplicate_ids) + target_pod_id = duplicate_ids.shift + + duplicate_ids.each do |pod_id| + Person.where(pod_id: pod_id).update_all(pod_id: target_pod_id) # rubocop:disable Rails/SkipsModelValidations + Pod.delete(pod_id) end end end diff --git a/spec/models/pod_spec.rb b/spec/models/pod_spec.rb index 4c41f0173..2e3bc9b09 100644 --- a/spec/models/pod_spec.rb +++ b/spec/models/pod_spec.rb @@ -43,6 +43,11 @@ describe Pod, type: :model do expect(pod.port).to eq(Pod::DEFAULT_PORT) end + it "normalizes hostname to lowercase" do + pod = Pod.find_or_create_by(url: "https://eXaMpLe.oRg/") + expect(pod.host).to eq("example.org") + end + context "validation" do it "is valid" do pod = Pod.find_or_create_by(url: "https://example.org/")