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 def find_or_create_by(opts) # Rename this method to not override an AR method
uri = URI.parse(opts.fetch(:url)) uri = URI.parse(opts.fetch(:url))
port = DEFAULT_PORTS.include?(uri.port) ? DEFAULT_PORT : uri.port 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.ssl ||= (uri.scheme == "https")
pod.save pod.save
end end
@ -168,6 +168,6 @@ class Pod < ApplicationRecord
def not_own_pod def not_own_pod
pod_uri = AppConfig.pod_uri pod_uri = AppConfig.pod_uri
pod_port = DEFAULT_PORTS.include?(pod_uri.port) ? DEFAULT_PORT : pod_uri.port 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
end end

View file

@ -8,6 +8,7 @@ class CleanupDuplicatePods < ActiveRecord::Migration[6.1]
reversible do |change| reversible do |change|
change.up do change.up do
remove_duplicates remove_duplicates
cleanup_mixed_case_pods
Pod.where(port: nil).update_all(port: -1) # rubocop:disable Rails/SkipsModelValidations Pod.where(port: nil).update_all(port: -1) # rubocop:disable Rails/SkipsModelValidations
end end
@ -24,7 +25,19 @@ class CleanupDuplicatePods < ActiveRecord::Migration[6.1]
def remove_duplicates def remove_duplicates
Pod.where(port: nil).group(:host).having("count(*) > 1").pluck(:host).each do |host| Pod.where(port: nil).group(:host).having("count(*) > 1").pluck(:host).each do |host|
duplicate_ids = Pod.where(host: host).order(:id).ids cleanup_duplicates(Pod.where(host: host).order(:id).ids)
end
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 target_pod_id = duplicate_ids.shift
duplicate_ids.each do |pod_id| duplicate_ids.each do |pod_id|
@ -33,4 +46,3 @@ class CleanupDuplicatePods < ActiveRecord::Migration[6.1]
end end
end end
end end
end

View file

@ -43,6 +43,11 @@ describe Pod, type: :model do
expect(pod.port).to eq(Pod::DEFAULT_PORT) expect(pod.port).to eq(Pod::DEFAULT_PORT)
end 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 context "validation" do
it "is valid" do it "is valid" do
pod = Pod.find_or_create_by(url: "https://example.org/") pod = Pod.find_or_create_by(url: "https://example.org/")