FIX: when searching PMs also search group PMs

Users belonging to a group could not search for PMs unless explicitly added
to the PM unless admin
This commit is contained in:
Sam 2017-05-11 15:58:43 -04:00
parent 10f2db67ba
commit 52ae63d5d7
3 changed files with 58 additions and 40 deletions

View File

@ -59,6 +59,18 @@ class Post < ActiveRecord::Base
SHORT_POST_CHARS = 1200
scope :private_posts_for_user, ->(user) {
where("posts.topic_id IN (SELECT topic_id
FROM topic_allowed_users
WHERE user_id = :user_id
UNION ALL
SELECT tg.topic_id
FROM topic_allowed_groups tg
JOIN group_users gu ON gu.user_id = :user_id AND
gu.group_id = tg.group_id)",
user_id: user.id)
}
scope :by_newest, -> { order('created_at desc, id desc') }
scope :by_post_number, -> { order('post_number ASC') }
scope :with_user, -> { includes(:user) }

View File

@ -610,7 +610,7 @@ class Search
posts = posts.where("topics.archetype = ?", Archetype.private_message)
unless @guardian.is_admin?
posts = posts.where("topics.id IN (SELECT topic_id FROM topic_allowed_users WHERE user_id = ?)", @guardian.user.id)
posts = posts.private_posts_for_user(@guardian.user)
end
else
posts = posts.where("topics.archetype <> ?", Archetype.private_message)
@ -654,15 +654,7 @@ class Search
if @search_context.is_a?(User)
if opts[:private_messages]
posts = posts.where("topics.id IN (SELECT topic_id
FROM topic_allowed_users
WHERE user_id = :user_id
UNION ALL
SELECT tg.topic_id
FROM topic_allowed_groups tg
JOIN group_users gu ON gu.user_id = :user_id AND
gu.group_id = tg.group_id)",
user_id: @search_context.id)
posts = posts.private_posts_for_user(@search_context)
else
posts = posts.where("posts.user_id = #{@search_context.id}")
end

View File

@ -159,50 +159,64 @@ describe Search do
it 'searches correctly' do
expect do
Search.execute('mars', type_filter: 'private_messages')
end.to raise_error(Discourse::InvalidAccess)
expect do
Search.execute('mars', type_filter: 'private_messages')
end.to raise_error(Discourse::InvalidAccess)
TopicAllowedUser.create!(user_id: reply.user_id, topic_id: topic.id)
TopicAllowedUser.create!(user_id: post.user_id, topic_id: topic.id)
TopicAllowedUser.create!(user_id: reply.user_id, topic_id: topic.id)
TopicAllowedUser.create!(user_id: post.user_id, topic_id: topic.id)
results = Search.execute('mars',
type_filter: 'private_messages',
guardian: Guardian.new(reply.user))
results = Search.execute('mars',
type_filter: 'private_messages',
guardian: Guardian.new(reply.user))
expect(results.posts.length).to eq(1)
expect(results.posts.length).to eq(1)
results = Search.execute('mars',
search_context: topic,
guardian: Guardian.new(reply.user))
results = Search.execute('mars',
search_context: topic,
guardian: Guardian.new(reply.user))
expect(results.posts.length).to eq(1)
expect(results.posts.length).to eq(1)
# does not leak out
results = Search.execute('mars',
type_filter: 'private_messages',
guardian: Guardian.new(Fabricate(:user)))
# does not leak out
results = Search.execute('mars',
type_filter: 'private_messages',
guardian: Guardian.new(Fabricate(:user)))
expect(results.posts.length).to eq(0)
expect(results.posts.length).to eq(0)
Fabricate(:topic, category_id: nil, archetype: 'private_message')
Fabricate(:post, topic: topic, raw: 'another secret pm from mars, testing')
Fabricate(:topic, category_id: nil, archetype: 'private_message')
Fabricate(:post, topic: topic, raw: 'another secret pm from mars, testing')
# admin can search everything with correct context
results = Search.execute('mars',
type_filter: 'private_messages',
search_context: post.user,
guardian: Guardian.new(Fabricate(:admin)))
# admin can search everything with correct context
results = Search.execute('mars',
type_filter: 'private_messages',
search_context: post.user,
guardian: Guardian.new(Fabricate(:admin)))
expect(results.posts.length).to eq(1)
expect(results.posts.length).to eq(1)
results = Search.execute('mars in:private',
search_context: post.user,
guardian: Guardian.new(post.user))
results = Search.execute('mars in:private',
search_context: post.user,
guardian: Guardian.new(post.user))
expect(results.posts.length).to eq(1)
expect(results.posts.length).to eq(1)
# can search group PMs as well as non admin
#
user = Fabricate(:user)
group = Fabricate.build(:group)
group.add(user)
group.save!
TopicAllowedGroup.create!(group_id: group.id, topic_id: topic.id)
results = Search.execute('mars in:private',
guardian: Guardian.new(user))
expect(results.posts.length).to eq(1)
end