diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index f32f85d3ffc08386c66946f421f73505330bea67..6abf2360d3d1036eec58f739a1dcca81ad46fdc8 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -146,7 +146,7 @@ def update end def export_csv - csv_params = filter_params.permit(IssuableFinder::VALID_PARAMS) + csv_params = IssuableFinder.valid_params(filter_params) ExportCsvWorker.perform_async(@current_user.id, @project.id, csv_params) index_path = namespace_project_issues_path(@project.namespace, @project) diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 75a271459101a9f0ece3693e10db7cc591057d8e..45b8e426d1908a73d660362888424330dff0c8f0 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -21,11 +21,15 @@ class IssuableFinder NONE = '0'.freeze VALID_PARAMS = %i(scope state group_id project_id milestone_title assignee_id search label_name sort assignee_username author_id author_username authorized_only due_date iids non_archived weight).freeze + VALID_ARRAY_PARAMS = { label_name: [], iids: [] }.freeze attr_accessor :current_user, :params def initialize(current_user, params = {}) @current_user = current_user + if invalid_params?(params) + raise ArgumentError, "Invalid issuable params" + end @params = params end @@ -49,6 +53,10 @@ def execute sort(items) end + def self.valid_params(params) + params.permit(*VALID_PARAMS, VALID_ARRAY_PARAMS) + end + def find(*params) execute.find(*params) end @@ -228,6 +236,10 @@ def init_collection klass.all end + def invalid_params?(params) + valid_params(params).keys != params.keys + end + def by_scope(items) case params[:scope] when 'created-by-me', 'authored' diff --git a/app/views/projects/issues/export_issues/_csv_download.html.haml b/app/views/projects/issues/export_issues/_csv_download.html.haml index 9f2fc729ec5c9374429f9771e9d286c83fb391a5..aa4b581312647b7f3f110c849f6d79e47d03ce3b 100644 --- a/app/views/projects/issues/export_issues/_csv_download.html.haml +++ b/app/views/projects/issues/export_issues/_csv_download.html.haml @@ -17,4 +17,4 @@ %strong= @current_user.notification_email in an attachment. .modal-footer - = link_to 'Export issues', export_csv_namespace_project_issues_path(@project.namespace, @project, params.permit(IssuableFinder::VALID_PARAMS)), method: :post, class: 'btn btn-success pull-left', title: 'Export issues' + = link_to 'Export issues', export_csv_namespace_project_issues_path(@project.namespace, @project, IssuableFinder.valid_params(params)), method: :post, class: 'btn btn-success pull-left', title: 'Export issues' diff --git a/spec/features/issues/csv_spec.rb b/spec/features/issues/csv_spec.rb index 46298255472e721e5b800e8b620e761d9bcedf11..4667859c4c8f5d4b0fcc1117d1f8dabd0fbe8418 100644 --- a/spec/features/issues/csv_spec.rb +++ b/spec/features/issues/csv_spec.rb @@ -63,6 +63,14 @@ def csv expect(csv.count).to eq 0 end + it 'uses array filters, such as label_name' do + issue.update!(labels: [idea_label]) + + request_csv("label_name[]" => 'Bug') + + expect(csv.count).to eq 0 + end + it 'avoids excessive database calls' do control_count = ActiveRecord::QueryRecorder.new{ request_csv }.count create_list(:labeled_issue,