FIX: Admin search for PMs should only search own PMs.

FIX: Admin search for PMs should only search own PMs.

In c6ceda8c, a bug was introduced where an admin searching for his own private messages will actually end up searching through all private messages on the site.

Follow-up to c6ceda8c4ed968db1e3517f00ff401204355d3b9

diff --git a/lib/search.rb b/lib/search.rb
index 23d274b..caa5edc 100644
--- a/lib/search.rb
+++ b/lib/search.rb
@@ -185,8 +185,13 @@ class Search
       @original_term = PG::Connection.escape_string(@term)
     end
 
-    if @search_pms
+    if @search_pms || @opts[:type_filter] == 'private_messages'
       @opts[:type_filter] = "private_messages"
+      @search_context ||= @guardian.user
+
+      unless @search_context.present? && @guardian.can_see_private_messages?(@search_context.id)
+        raise Discourse::InvalidAccess.new
+      end
     end
 
     if @search_all_topics && @guardian.user
@@ -694,8 +699,6 @@ class Search
         @search_pms = true
         nil
       elsif word =~ /^personal_messages:(.+)$/
-        raise Discourse::InvalidAccess.new unless @guardian.is_admin?
-
         if user = User.find_by_username($1)
           @search_pms = true
           @search_context = user
@@ -900,7 +903,7 @@ class Search
       if @search_context.present?
         if @search_context.is_a?(User)
           if type_filter === "private_messages"
-            posts.private_posts_for_user(@search_context)
+            @guardian.is_admin? ? posts.private_posts_for_user(@search_context) : posts
           else
             posts.where("posts.user_id = #{@search_context.id}")
           end
diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb
index 06eb0f5..97c1cf5 100644
--- a/spec/components/search_spec.rb
+++ b/spec/components/search_spec.rb
@@ -208,57 +208,75 @@ describe Search do
       )
     end
 
-    it 'searches correctly' do
-      expect do
-        Search.execute('mars', type_filter: 'private_messages')
-      end.to raise_error(Discourse::InvalidAccess)
-
+    it 'searches correctly as an admin' do
       results = Search.execute(
         'mars',
         type_filter: 'private_messages',
-        guardian: Guardian.new(reply.user)
+        guardian: Guardian.new(admin)
       )
 
-      expect(results.posts).to contain_exactly(reply)
+      expect(results.posts).to eq([])
+    end
 
+    it "searches correctly as an admin given another user's context" do
       results = Search.execute(
         'mars',
         type_filter: 'private_messages',
+        search_context: reply.user,
         guardian: Guardian.new(admin)
       )
 
-      expect(results.posts).to contain_exactly(reply, post2)
+      expect(results.posts).to contain_exactly(reply)
+    end
+
+    it "raises the right error when a normal user searches for another user's context" do
+      expect do
+        Search.execute(
+          'mars',
+          search_context: reply.user,
+          type_filter: 'private_messages',
+          guardian: Guardian.new(Fabricate(:user))
+        )
+      end.to raise_error(Discourse::InvalidAccess)
+    end
 
+    it 'searches correctly as a user' do
       results = Search.execute(
         'mars',
-        search_context: topic,
+        type_filter: 'private_messages',
         guardian: Guardian.new(reply.user)
       )
 
       expect(results.posts).to contain_exactly(reply)
+    end
 
-      # does not leak out
+    it 'searches correctly for a user with no private messages' do
       results = Search.execute(
         'mars',
         type_filter: 'private_messages',
         guardian: Guardian.new(Fabricate(:user))
-      )
+       )
 
-      expect(results.posts.empty?).to eq(true)
+      expect(results.posts).to eq([])
+    end
+
+    it 'searches correctly' do
+      expect do
+        Search.execute('mars', type_filter: 'private_messages')
+      end.to raise_error(Discourse::InvalidAccess)
 
-      # admin can search everything with correct context
       results = Search.execute(
         'mars',
         type_filter: 'private_messages',
-        search_context: post.user,
-        guardian: Guardian.new(admin)
+        guardian: Guardian.new(reply.user)
       )
 
       expect(results.posts).to contain_exactly(reply)
 
       results = Search.execute(
-        'mars in:personal',
-        guardian: Guardian.new(post.user)
+        'mars',
+        search_context: topic,
+        guardian: Guardian.new(reply.user)
       )
 
       expect(results.posts).to contain_exactly(reply)
@@ -285,7 +303,7 @@ describe Search do
         expect do
           results = Search.execute(
             "mars personal_messages:#{post.user.username}",
-            guardian: Guardian.new(post.user)
+            guardian: Guardian.new(Fabricate(:user))
           )
         end.to raise_error(Discourse::InvalidAccess)
       end

GitHub sha: e6ca1b43