Browse Source

Fixes #4425 - Search doesn't show tickets belonging to secondary organizations.

Rolf Schmidt 2 years ago
parent
commit
6314da1713

+ 10 - 13
app/models/ticket/search.rb

@@ -141,19 +141,16 @@ returns
           end
         end
         if current_user.permissions?('ticket.customer')
-          access_condition = if !current_user.organization || (!current_user.organization.shared || current_user.organization.shared == false)
-                               {
-                                 'query_string' => { 'default_field' => 'customer_id', 'query' => current_user.id }
-                               }
-                             #  customer_id: XXX
-                             #          conditions = [ 'customer_id = ?', current_user.id ]
-                             else
-                               {
-                                 'query_string' => { 'query' => "customer_id:#{current_user.id} OR organization_id:#{current_user.organization.id}" }
-                               }
-                               # customer_id: XXX OR organization_id: XXX
-                               #          conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
-                             end
+          organizations_query = current_user.all_organizations.where(shared: true).map { |o| "organization_id:#{o.id}" }.join(' OR ')
+          access_condition    = if organizations_query.present?
+                                  {
+                                    'query_string' => { 'query' => "customer_id:#{current_user.id} OR #{organizations_query}" }
+                                  }
+                                else
+                                  {
+                                    'query_string' => { 'default_field' => 'customer_id', 'query' => current_user.id }
+                                  }
+                                end
           query_or.push(access_condition)
         end
 

+ 4 - 0
app/models/user.rb

@@ -919,6 +919,10 @@ try to find correct name
     Organization.where(id: all_organization_ids).any?(&:shared)
   end
 
+  def all_organizations
+    Organization.where(id: all_organization_ids)
+  end
+
   def all_organization_ids
     ([organization_id] + organization_ids).uniq
   end

+ 5 - 0
app/models/user/search_index.rb

@@ -18,6 +18,11 @@ class User
           attributes['permissions'].push permission.name
         end
         attributes['role_ids'] = role_ids
+
+        attributes['organization_ids'] = organization_ids
+        attributes['organizations']    = organizations.each_with_object([]) do |organization, result|
+          result << organization.search_index_attribute_lookup(include_references: false)
+        end
       end
 
       attributes

+ 67 - 0
spec/models/ticket/has_search_index_backend_spec.rb

@@ -100,4 +100,71 @@ RSpec.describe 'HasSearchIndexBackend', performs_jobs: true, searchindex: true,
       expect(Delayed::Job.where("handler LIKE '%SearchIndexJob%' AND handler LIKE '%Organization%'").count).to be > 0
     end
   end
+
+  describe 'Search doesnt show tickets belonging to secondary organization #4425' do
+    let(:organization_a) { create(:organization, shared: true) }
+    let(:organization_b) { create(:organization, shared: false) }
+
+    let(:customer_a) { create(:customer, :with_org, organizations: [organization_a, organization_b]) }
+    let(:customer_b) { create(:customer, :with_org, organizations: [organization_a, organization_b]) }
+
+    let(:ticket_customer_a_shared) do
+      ticket = create(:ticket, title: 'findme', customer: customer_a, organization: organization_a)
+      create(:ticket_article, ticket: ticket)
+      ticket
+    end
+    let(:ticket_customer_a_nonshared) do
+      ticket = create(:ticket, title: 'findme', customer: customer_a, organization: organization_b)
+      create(:ticket_article, ticket: ticket)
+      ticket
+    end
+    let(:ticket_customer_b_shared) do
+      ticket = create(:ticket, title: 'findme', customer: customer_b, organization: organization_a)
+      create(:ticket_article, ticket: ticket)
+      ticket
+    end
+    let(:ticket_customer_b_nonshared) do
+      ticket = create(:ticket, title: 'findme', customer: customer_b, organization: organization_b)
+      create(:ticket_article, ticket: ticket)
+      ticket
+    end
+
+    before do
+      ticket_customer_a_shared
+      ticket_customer_a_nonshared
+      ticket_customer_b_shared
+      ticket_customer_b_nonshared
+      searchindex_model_reload([Ticket, User, Organization])
+    end
+
+    context 'with ES' do
+      it 'customer does find shared tickets', :aggregate_failures do
+        result = Ticket.search(
+          current_user: customer_a,
+          query:        'findme',
+          full:         true,
+        )
+
+        expect(result).to include(ticket_customer_a_shared)
+        expect(result).to include(ticket_customer_a_nonshared)
+        expect(result).to include(ticket_customer_b_shared)
+        expect(result).not_to include(ticket_customer_b_nonshared)
+      end
+    end
+
+    context 'with DB', searchindex: false do
+      it 'customer does find shared tickets', :aggregate_failures do
+        result = Ticket.search(
+          current_user: customer_a,
+          query:        'findme',
+          full:         true,
+        )
+
+        expect(result).to include(ticket_customer_a_shared)
+        expect(result).to include(ticket_customer_a_nonshared)
+        expect(result).to include(ticket_customer_b_shared)
+        expect(result).not_to include(ticket_customer_b_nonshared)
+      end
+    end
+  end
 end

+ 14 - 0
spec/models/user/has_search_index_backend_spec.rb

@@ -49,4 +49,18 @@ RSpec.describe 'HasSearchIndexBackend', searchindex: true, type: :model do
       expect { user.update(firstname: user.firstname) }.not_to change(Delayed::Job, :count)
     end
   end
+
+  describe 'Search doesnt show tickets belonging to secondary organization #4425' do
+    let(:user) { create(:user, organization: create(:organization), organizations: [create(:organization, name: SecureRandom.uuid)]) }
+
+    before do
+      user
+      searchindex_model_reload([User, Organization])
+    end
+
+    it 'does find user by secondary organization' do
+      result = SearchIndexBackend.search(user.organizations.first.name, 'User', sort_by: ['updated_at'], order_by: ['desc'])
+      expect(result).to eq([{ id: user.id.to_s, type: 'User' }])
+    end
+  end
 end