Merge pull request #10774 from mfo/US/fix-PG-NumericValueOutOfRange
correctif: ETQ instructeur, si j'ai essayé de filtrer mes dossiers par numéro et que j'ai saisi un numero superieur à 2147483647, ma page ne doit pas planter
This commit is contained in:
commit
7bbf04b9b5
5 changed files with 79 additions and 2 deletions
|
@ -95,9 +95,7 @@ module Instructeurs
|
|||
|
||||
@has_export_notification = notify_exports?
|
||||
@last_export = last_export_for(statut)
|
||||
|
||||
@filtered_sorted_ids = procedure_presentation.filtered_sorted_ids(dossiers, statut, count: dossiers_count)
|
||||
|
||||
page = params[:page].presence || 1
|
||||
|
||||
@dossiers_count = @filtered_sorted_ids.size
|
||||
|
|
|
@ -14,6 +14,8 @@ class ProcedurePresentation < ApplicationRecord
|
|||
TYPE_DE_CHAMP = 'type_de_champ'
|
||||
|
||||
FILTERS_VALUE_MAX_LENGTH = 100
|
||||
# https://www.postgresql.org/docs/current/datatype-numeric.html
|
||||
PG_INTEGER_MAX_VALUE = 2147483647
|
||||
|
||||
belongs_to :assign_to, optional: false
|
||||
has_many :exports, dependent: :destroy
|
||||
|
@ -25,6 +27,7 @@ class ProcedurePresentation < ApplicationRecord
|
|||
validate :check_allowed_sort_order
|
||||
validate :check_allowed_filter_columns
|
||||
validate :check_filters_max_length
|
||||
validate :check_filters_max_integer
|
||||
|
||||
def displayed_fields_for_headers
|
||||
[
|
||||
|
@ -313,6 +316,16 @@ class ProcedurePresentation < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def check_filters_max_integer
|
||||
filters.values.flatten.each do |filter|
|
||||
next if !filter.is_a?(Hash)
|
||||
next if filter['column'] != 'id'
|
||||
next if filter['value']&.to_i&. < PG_INTEGER_MAX_VALUE
|
||||
|
||||
errors.add(:base, "Le filtre #{filter['label']} n'est pas un numéro de dossier possible")
|
||||
end
|
||||
end
|
||||
|
||||
def valid_column?(table, column, extra_columns = {})
|
||||
valid_columns_for_table(table).include?(column) ||
|
||||
extra_columns[table]&.include?(column)
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Maintenance
|
||||
# PR: 10774
|
||||
# why: postgres does not support integer greater than ProcedurePresentation::PG_INTEGER_MAX_VALUE)
|
||||
# it occures when user copypaste the dossier id twice (like missed copy paste,paste)
|
||||
# once this huge integer is saved on procedure presentation, page with this filter can't be loaded
|
||||
# when: run this migration when it appears in your maintenance tasks list, this file fix the data and we added some validations too
|
||||
class CleanInvalidProcedurePresentationTask < MaintenanceTasks::Task
|
||||
def collection
|
||||
ProcedurePresentation.all
|
||||
end
|
||||
|
||||
def process(element)
|
||||
element.filters = element.filters.transform_values do |filters_by_status|
|
||||
filters_by_status.reject do |filter|
|
||||
filter.is_a?(Hash) &&
|
||||
filter['column'] == 'id' &&
|
||||
(filter['value']&.to_i&. >= ProcedurePresentation::PG_INTEGER_MAX_VALUE)
|
||||
end
|
||||
end
|
||||
element.save
|
||||
end
|
||||
|
||||
def count
|
||||
# Optionally, define the number of rows that will be iterated over
|
||||
# This is used to track the task's progress
|
||||
end
|
||||
end
|
||||
end
|
|
@ -55,6 +55,11 @@ describe ProcedurePresentation do
|
|||
context 'of filters' do
|
||||
it { expect(build(:procedure_presentation, filters: { "suivis" => [{ table: "user", column: "reset_password_token", "order" => "asc" }] })).to be_invalid }
|
||||
it { expect(build(:procedure_presentation, filters: { "suivis" => [{ table: "user", column: "email", "value" => "exceedingly long filter value" * 10 }] })).to be_invalid }
|
||||
|
||||
describe 'check_filters_max_integer' do
|
||||
it { expect(build(:procedure_presentation, filters: { "suivis" => [{ table: "self", column: "id", "value" => ProcedurePresentation::PG_INTEGER_MAX_VALUE.to_s }] })).to be_invalid }
|
||||
it { expect(build(:procedure_presentation, filters: { "suivis" => [{ table: "self", column: "id", "value" => (ProcedurePresentation::PG_INTEGER_MAX_VALUE - 1).to_s }] })).to be_valid }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
module Maintenance
|
||||
RSpec.describe CleanInvalidProcedurePresentationTask do
|
||||
describe "#process" do
|
||||
subject(:process) { described_class.process(element) }
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:groupe_instructeur) { create(:groupe_instructeur, procedure:, instructeurs: [build(:instructeur)]) }
|
||||
let(:assign_to) { create(:assign_to, procedure:, instructeur: groupe_instructeur.instructeurs.first) }
|
||||
let(:element) { create(:procedure_presentation, procedure:, assign_to:) }
|
||||
|
||||
before { element.update_column(:filters, filters) }
|
||||
|
||||
context 'when filter is valid' do
|
||||
let(:filters) { { "suivis" => [{ 'table' => "self", 'column' => "id", "value" => (ProcedurePresentation::PG_INTEGER_MAX_VALUE - 1).to_s }] } }
|
||||
it 'keeps it filters' do
|
||||
expect { subject }.not_to change { element.reload.filters }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when filter is invalid, drop it' do
|
||||
let(:filters) { { "suivis" => [{ 'table' => "self", 'column' => "id", "value" => (ProcedurePresentation::PG_INTEGER_MAX_VALUE).to_s }] } }
|
||||
it 'drop invalid filters' do
|
||||
expect { subject }.to change { element.reload.filters }.to({ "suivis" => [] })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue