diff --git a/lib/search.rb b/lib/search.rb index 23d274b6010..caa5edca206 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 06eb0f5fbe9..97c1cf58754 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -208,6 +208,58 @@ describe Search do ) end + it 'searches correctly as an admin' do + results = Search.execute( + 'mars', + type_filter: 'private_messages', + guardian: Guardian.new(admin) + ) + + 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) + 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', + type_filter: 'private_messages', + guardian: Guardian.new(reply.user) + ) + + expect(results.posts).to contain_exactly(reply) + end + + 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).to eq([]) + end + it 'searches correctly' do expect do Search.execute('mars', type_filter: 'private_messages') @@ -221,14 +273,6 @@ describe Search do expect(results.posts).to contain_exactly(reply) - results = Search.execute( - 'mars', - type_filter: 'private_messages', - guardian: Guardian.new(admin) - ) - - expect(results.posts).to contain_exactly(reply, post2) - results = Search.execute( 'mars', search_context: topic, @@ -237,32 +281,6 @@ describe Search do expect(results.posts).to contain_exactly(reply) - # does not leak out - results = Search.execute( - 'mars', - type_filter: 'private_messages', - guardian: Guardian.new(Fabricate(:user)) - ) - - expect(results.posts.empty?).to eq(true) - - # admin can search everything with correct context - results = Search.execute( - 'mars', - type_filter: 'private_messages', - search_context: post.user, - guardian: Guardian.new(admin) - ) - - expect(results.posts).to contain_exactly(reply) - - results = Search.execute( - 'mars in:personal', - guardian: Guardian.new(post.user) - ) - - expect(results.posts).to contain_exactly(reply) - # can search group PMs as well as non admin # user = Fabricate(:user) @@ -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