diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 7bf963212..136edfad8 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -59,17 +59,25 @@ class LettingsLog < Log query.all } scope :search_by, lambda { |param| - by_id = Arel.sql("CASE WHEN lettings_logs.id = #{param.to_i} THEN 0 ELSE 1 END") - by_tenant_code = Arel.sql("CASE WHEN tenancycode = '#{param}' THEN 0 WHEN tenancycode ILIKE '%#{param}%' THEN 1 ELSE 2 END") - by_propcode = Arel.sql("CASE WHEN propcode = '#{param}' THEN 0 WHEN propcode ILIKE '%#{param}%' THEN 1 ELSE 2 END") - by_postcode = Arel.sql("CASE WHEN REPLACE(postcode_full, ' ', '') = '#{param.delete(' ')}' THEN 0 when REPLACE(postcode_full, ' ', '') ILIKE '%#{param.delete(' ')}%' then 1 ELSE 2 END") + sanitized_order_param = ActiveRecord::Base.sanitize_sql_for_order(param) + order_param_without_spaces = sanitized_order_param.delete(" ") + + by_id = Arel.sql("CASE WHEN lettings_logs.id = ? THEN 0 ELSE 1 END") + by_tenant_code = Arel.sql("CASE WHEN tenancycode = ? THEN 0 WHEN tenancycode ILIKE ? THEN 1 ELSE 2 END") + by_propcode = Arel.sql("CASE WHEN propcode = ? THEN 0 WHEN propcode ILIKE ? THEN 1 ELSE 2 END") + by_postcode = Arel.sql("CASE WHEN REPLACE(postcode_full, ' ', '') = ? THEN 0 WHEN REPLACE(postcode_full, ' ', '') ILIKE ? THEN 1 ELSE 2 END") filter_by_location_postcode(param) .or(filter_by_tenant_code(param)) .or(filter_by_propcode(param)) .or(filter_by_postcode(param)) .or(filter_by_id(param.gsub(/log/i, ""))) - .order(by_id, by_tenant_code, by_propcode, by_postcode) + .order( + [by_id, sanitized_order_param.to_i], + [by_tenant_code, sanitized_order_param, sanitized_order_param], + [by_propcode, sanitized_order_param, sanitized_order_param], + [by_postcode, order_param_without_spaces, order_param_without_spaces], + ) } scope :after_date, ->(date) { where("lettings_logs.startdate >= ?", date) } scope :before_date, ->(date) { where("lettings_logs.startdate < ?", date) } diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 8312b8bff..1c748582e 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -46,14 +46,19 @@ class SalesLog < Log } scope :filter_by_purchaser_code, ->(purchid) { where("purchid ILIKE ?", "%#{purchid}%") } scope :search_by, lambda { |param| - by_id = Arel.sql("CASE WHEN id = #{param.to_i} THEN 0 ELSE 1 END") - by_purchaser_code = Arel.sql("CASE WHEN purchid = '#{param}' THEN 0 WHEN purchid ILIKE '%#{param}%' THEN 1 ELSE 2 END") - by_postcode = Arel.sql("CASE WHEN REPLACE(postcode_full, ' ', '') = '#{param.delete(' ')}' THEN 0 WHEN REPLACE(postcode_full, ' ', '') ILIKE '%#{param.delete(' ')}%' THEN 1 ELSE 2 END") + sanitized_order_param = ActiveRecord::Base.sanitize_sql_for_order(param) + order_param_without_spaces = sanitized_order_param.delete(" ") + + by_id = Arel.sql("CASE WHEN id = ? THEN 0 ELSE 1 END") + by_purchaser_code = Arel.sql("CASE WHEN purchid = ? THEN 0 WHEN purchid ILIKE ? THEN 1 ELSE 2 END") + by_postcode = Arel.sql("CASE WHEN REPLACE(postcode_full, ' ', '') = ? THEN 0 WHEN REPLACE(postcode_full, ' ', '') ILIKE ? THEN 1 ELSE 2 END") filter_by_purchaser_code(param) .or(filter_by_postcode(param)) .or(filter_by_id(param.gsub(/log/i, ""))) - .order(by_id, by_purchaser_code, by_postcode) + .order([by_id, sanitized_order_param.to_i], + [by_purchaser_code, sanitized_order_param, sanitized_order_param], + [by_postcode, order_param_without_spaces, order_param_without_spaces]) } scope :age1_answered, -> { where.not(age1: nil).or(where(age1_known: [1, 2])) } scope :duplicate_logs, lambda { |log| diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index 92452f197..e28f0f2c5 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -1345,6 +1345,13 @@ RSpec.describe LettingsLog do expect(result.third.id).to eq lettings_log_with_postcode.id end end + + it "sanitises input for order" do + lettings_log_to_search.update!(tenancycode: "' 1234") + result = described_class.search_by(lettings_log_to_search.tenancycode) + expect(result.count).to eq(1) + expect(result.first.id).to eq lettings_log_to_search.id + end end end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index a568ca330..ae9b00d4c 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -214,6 +214,13 @@ RSpec.describe SalesLog, type: :model do expect(result).to include(have_attributes(id: sales_log_to_search.id)) end end + + it "sanitises input for order" do + sales_log_to_search.update!(purchid: "' 123456") + result = described_class.search_by(sales_log_to_search.purchid) + expect(result.count).to be >= 1 + expect(result).to include(have_attributes(id: sales_log_to_search.id)) + end end context "when filtering by year or nil" do