Ensure pod urls are always lowercase

otherwise pods can exist multiple times with mixed case
This commit is contained in:
Benjamin Neff 2022-10-31 00:43:50 +01:00
parent 6bdf6f03b4
commit 8334eeeeff
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
3 changed files with 25 additions and 8 deletions

View file

@ -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

View file

@ -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

View file

@ -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/")