Fixes #2517 - Elasticsearch throws error 500 when filtering for owner or custom dropdown-fields inside of report profiles.

This commit is contained in:
Rolf Schmidt 2020-10-07 16:53:52 +02:00 committed by Thorsten Eckel
parent 73f08e8f77
commit 72dd0c0316
4 changed files with 86 additions and 4 deletions

View file

@ -39,6 +39,7 @@ class ReportsController < ApplicationController
params: backend[:params], params: backend[:params],
timezone: get_params[:timezone], timezone: get_params[:timezone],
timezone_offset: get_params[:timezone_offset], timezone_offset: get_params[:timezone_offset],
current_user: current_user
) )
end end
@ -83,6 +84,7 @@ class ReportsController < ApplicationController
sheet: params[:sheet], sheet: params[:sheet],
timezone: get_params[:timezone], timezone: get_params[:timezone],
timezone_offset: get_params[:timezone_offset], timezone_offset: get_params[:timezone_offset],
current_user: current_user
) )
result = { count: 0, ticket_ids: [] } if result.nil? result = { count: 0, ticket_ids: [] } if result.nil?

View file

@ -45,7 +45,7 @@ returns
end end
selector.merge!(without_merged_tickets) # do not show merged tickets in reports selector.merge!(without_merged_tickets) # do not show merged tickets in reports
result_es = SearchIndexBackend.selectors('Ticket', selector, {}, aggs_interval) result_es = SearchIndexBackend.selectors('Ticket', selector, { current_user: params[:current_user] }, aggs_interval)
case params[:interval] case params[:interval]
when 'month' when 'month'
stop_interval = 12 stop_interval = 12
@ -170,7 +170,7 @@ returns
end end
selector.merge!(without_merged_tickets) # do not show merged tickets in reports selector.merge!(without_merged_tickets) # do not show merged tickets in reports
result = SearchIndexBackend.selectors('Ticket', selector, { limit: limit }, aggs_interval) result = SearchIndexBackend.selectors('Ticket', selector, { current_user: params[:current_user], limit: limit }, aggs_interval)
return result if params[:sheet].present? return result if params[:sheet].present?
assets = {} assets = {}

View file

@ -473,6 +473,12 @@ example for aggregations within one year
def self.selector2query(selector, options, aggs_interval) def self.selector2query(selector, options, aggs_interval)
options = DEFAULT_QUERY_OPTIONS.merge(options.deep_symbolize_keys) options = DEFAULT_QUERY_OPTIONS.merge(options.deep_symbolize_keys)
current_user = options[:current_user]
current_user_id = UserInfo.current_user_id
if current_user
current_user_id = current_user.id
end
query_must = [] query_must = []
query_must_not = [] query_must_not = []
relative_map = { relative_map = {
@ -493,6 +499,32 @@ example for aggregations within one year
# use .keyword in case of compare exact values # use .keyword in case of compare exact values
if data['operator'] == 'is' || data['operator'] == 'is not' if data['operator'] == 'is' || data['operator'] == 'is not'
case data['pre_condition']
when 'not_set'
data['value'] = if key_tmp.match?(/^(created_by|updated_by|owner|customer|user)_id/)
1
else
'NULL'
end
when 'current_user.id'
raise "Use current_user.id in selector, but no current_user is set #{data.inspect}" if !current_user_id
data['value'] = []
wildcard_or_term = 'terms'
if key_tmp == 'out_of_office_replacement_id'
data['value'].push User.find(current_user_id).out_of_office_agent_of.pluck(:id)
else
data['value'].push current_user_id
end
when 'current_user.organization_id'
raise "Use current_user.id in selector, but no current_user is set #{data.inspect}" if !current_user_id
user = User.find_by(id: current_user_id)
data['value'] = user.organization_id
end
if data['value'].is_a?(Array) if data['value'].is_a?(Array)
data['value'].each do |value| data['value'].each do |value|
next if !value.is_a?(String) || value !~ /[A-z]/ next if !value.is_a?(String) || value !~ /[A-z]/

View file

@ -164,14 +164,17 @@ RSpec.describe SearchIndexBackend, searchindex: true do
describe '.selectors' do describe '.selectors' do
let(:ticket1) { create :ticket, title: 'some-title1', state_id: 1 } let(:organization1) { create :organization }
let(:agent1) { create :agent, organization: organization1 }
let(:customer1) { create :customer, organization: organization1 }
let(:ticket1) { create :ticket, title: 'some-title1', state_id: 1, created_by: agent1 }
let(:ticket2) { create :ticket, title: 'some_title2', state_id: 4 } let(:ticket2) { create :ticket, title: 'some_title2', state_id: 4 }
let(:ticket3) { create :ticket, title: 'some::title3', state_id: 1 } let(:ticket3) { create :ticket, title: 'some::title3', state_id: 1 }
let(:ticket4) { create :ticket, title: 'phrase some-title4', state_id: 1 } let(:ticket4) { create :ticket, title: 'phrase some-title4', state_id: 1 }
let(:ticket5) { create :ticket, title: 'phrase some_title5', state_id: 1 } let(:ticket5) { create :ticket, title: 'phrase some_title5', state_id: 1 }
let(:ticket6) { create :ticket, title: 'phrase some::title6', state_id: 1 } let(:ticket6) { create :ticket, title: 'phrase some::title6', state_id: 1 }
let(:ticket7) { create :ticket, title: 'some title7', state_id: 1 } let(:ticket7) { create :ticket, title: 'some title7', state_id: 1 }
let(:ticket8) { create :ticket, title: 'sometitle', state_id: 1 } let(:ticket8) { create :ticket, title: 'sometitle', state_id: 1, owner: agent1, customer: customer1 }
before do before do
Ticket.destroy_all # needed to remove not created tickets Ticket.destroy_all # needed to remove not created tickets
@ -194,6 +197,51 @@ RSpec.describe SearchIndexBackend, searchindex: true do
end end
context 'query with contains' do context 'query with contains' do
it 'finds records with pre_condition not_set' do
result = described_class.selectors('Ticket',
{
'created_by_id' => {
'pre_condition' => 'not_set',
'operator' => 'is',
},
},
{},
{
field: 'created_at', # sort to verify result
})
expect(result).to eq({ count: 7, ticket_ids: [ticket8.id.to_s, ticket7.id.to_s, ticket6.id.to_s, ticket5.id.to_s, ticket4.id.to_s, ticket3.id.to_s, ticket2.id.to_s] })
end
it 'finds records with pre_condition current_user.id' do
result = described_class.selectors('Ticket',
{
'owner_id' => {
'pre_condition' => 'current_user.id',
'operator' => 'is',
},
},
{ current_user: agent1 },
{
field: 'created_at', # sort to verify result
})
expect(result).to eq({ count: 1, ticket_ids: [ticket8.id.to_s] })
end
it 'finds records with pre_condition current_user.organization_id' do
result = described_class.selectors('Ticket',
{
'organization_id' => {
'pre_condition' => 'current_user.organization_id',
'operator' => 'is',
},
},
{ current_user: agent1 },
{
field: 'created_at', # sort to verify result
})
expect(result).to eq({ count: 1, ticket_ids: [ticket8.id.to_s] })
end
it 'finds records with containing phrase' do it 'finds records with containing phrase' do
result = described_class.selectors('Ticket', result = described_class.selectors('Ticket',
{ {