search: fix searches for private favorites raising privilege errors.
* Fix fav:<user> searches to return no results instead of raising a UserPrivilege error when the user has private favorites. * Fix fav:<nonexistent_user> raising a UserPrivilege error instead of returning no results. * Fix -ordfav:<user> not being supported.
This commit is contained in:
@@ -14,7 +14,7 @@ class PostQueryBuilder
|
||||
METATAGS = %w[
|
||||
-user user -approver approver -commenter commenter comm -noter noter
|
||||
-noteupdater noteupdater artcomm -pool pool ordpool -favgroup favgroup -fav
|
||||
fav ordfav md5 -rating rating -locked locked width height mpixels ratio
|
||||
fav -ordfav ordfav md5 -rating rating -locked locked width height mpixels ratio
|
||||
score favcount filesize source -source id -id date age order limit -status
|
||||
status tagcount parent -parent child pixiv_id pixiv search -upvote upvote
|
||||
-downvote downvote filetype -filetype flagger -flagger appealer -appealer
|
||||
@@ -475,8 +475,6 @@ class PostQueryBuilder
|
||||
relation = relation.bit_flags_match(:has_embedded_notes, false)
|
||||
end
|
||||
|
||||
relation = add_tag_string_search_relation(q[:tags], relation)
|
||||
|
||||
if q[:ordpool].present?
|
||||
pool_name = q[:ordpool]
|
||||
|
||||
@@ -511,12 +509,40 @@ class PostQueryBuilder
|
||||
relation = add_user_subquery_relation(PostVote.negative.visible(CurrentUser.user), downvoter, relation, field: :user).negate
|
||||
end
|
||||
|
||||
if q[:ordfav].present?
|
||||
user_id = q[:ordfav].to_i
|
||||
relation = relation.joins("INNER JOIN favorites ON favorites.post_id = posts.id")
|
||||
relation = relation.where("favorites.user_id % 100 = ? and favorites.user_id = ?", user_id % 100, user_id).order("favorites.id DESC")
|
||||
q[:fav_neg].to_a.each do |username|
|
||||
favuser = User.find_by_name(username)
|
||||
|
||||
if favuser.present? && Pundit.policy!([CurrentUser.user, nil], favuser).can_see_favorites?
|
||||
q[:tags][:exclude] << "fav:#{favuser.id}"
|
||||
else
|
||||
relation = relation.all # no-op; excluding a nonexistent user returns everything
|
||||
end
|
||||
end
|
||||
|
||||
q[:fav].to_a.each do |username|
|
||||
favuser = User.find_by_name(username)
|
||||
|
||||
if favuser.present? && Pundit.policy!([CurrentUser.user, nil], favuser).can_see_favorites?
|
||||
q[:tags][:related] << "fav:#{favuser.id}"
|
||||
else
|
||||
relation = relation.none
|
||||
end
|
||||
end
|
||||
|
||||
q[:ordfav].to_a.each do |username|
|
||||
favuser = User.find_by_name(username)
|
||||
|
||||
if favuser.present? && Pundit.policy!([CurrentUser.user, nil], favuser).can_see_favorites?
|
||||
q[:tags][:related] << "fav:#{favuser.id}"
|
||||
relation = relation.joins("INNER JOIN favorites ON favorites.post_id = posts.id")
|
||||
relation = relation.where("favorites.user_id % 100 = ? and favorites.user_id = ?", favuser.id % 100, favuser.id).order("favorites.id DESC")
|
||||
else
|
||||
relation = relation.none
|
||||
end
|
||||
end
|
||||
|
||||
relation = add_tag_string_search_relation(q[:tags], relation)
|
||||
|
||||
# HACK: if we're using a date: or age: metatag, default to ordering by
|
||||
# created_at instead of id so that the query will use the created_at index.
|
||||
if q[:date].present? || q[:age].present?
|
||||
@@ -791,33 +817,17 @@ class PostQueryBuilder
|
||||
q[:favgroup] ||= []
|
||||
q[:favgroup] << g2
|
||||
|
||||
when "-fav"
|
||||
favuser = User.find_by_name(g2)
|
||||
|
||||
if favuser.nil? || !Pundit.policy!([CurrentUser.user, nil], favuser).can_see_favorites?
|
||||
raise User::PrivilegeError
|
||||
end
|
||||
|
||||
q[:tags][:exclude] << "fav:#{favuser.id}"
|
||||
when "-fav", "-ordfav"
|
||||
q[:fav_neg] ||= []
|
||||
q[:fav_neg] << g2
|
||||
|
||||
when "fav"
|
||||
favuser = User.find_by_name(g2)
|
||||
|
||||
if favuser.nil? || !Pundit.policy!([CurrentUser.user, nil], favuser).can_see_favorites?
|
||||
raise User::PrivilegeError
|
||||
end
|
||||
|
||||
q[:tags][:related] << "fav:#{favuser.id}"
|
||||
q[:fav] ||= []
|
||||
q[:fav] << g2
|
||||
|
||||
when "ordfav"
|
||||
favuser = User.find_by_name(g2)
|
||||
|
||||
if favuser.nil? || !Pundit.policy!([CurrentUser.user, nil], favuser).can_see_favorites?
|
||||
raise User::PrivilegeError.new
|
||||
end
|
||||
|
||||
q[:tags][:related] << "fav:#{favuser.id}"
|
||||
q[:ordfav] = favuser.id
|
||||
q[:ordfav] ||= []
|
||||
q[:ordfav] << g2
|
||||
|
||||
when "search"
|
||||
q[:saved_searches] ||= []
|
||||
|
||||
@@ -2016,13 +2016,25 @@ class PostTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
should "return posts for the fav:<name> metatag" do
|
||||
users = FactoryBot.create_list(:user, 2)
|
||||
posts = users.map do |u|
|
||||
CurrentUser.scoped(u) { FactoryBot.create(:post, tag_string: "fav:#{u.name}") }
|
||||
end
|
||||
user1 = create(:user)
|
||||
user2 = create(:user)
|
||||
user3 = create(:user, enable_private_favorites: true)
|
||||
post1 = as(user1) { create(:post, tag_string: "fav:true") }
|
||||
post2 = as(user2) { create(:post, tag_string: "fav:true") }
|
||||
post3 = as(user3) { create(:post, tag_string: "fav:true") }
|
||||
|
||||
assert_tag_match([posts[0]], "fav:#{users[0].name}")
|
||||
assert_tag_match([posts[1]], "-fav:#{users[0].name}")
|
||||
assert_tag_match([post1], "fav:#{user1.name}")
|
||||
assert_tag_match([post2], "fav:#{user2.name}")
|
||||
assert_tag_match([], "fav:#{user3.name}")
|
||||
assert_tag_match([], "fav:dne")
|
||||
|
||||
assert_tag_match([post3, post2], "-fav:#{user1.name}")
|
||||
assert_tag_match([post3, post2, post1], "-fav:dne")
|
||||
|
||||
as(user3) do
|
||||
assert_tag_match([post3], "fav:#{user3.name}")
|
||||
assert_tag_match([post2, post1], "-fav:#{user3.name}")
|
||||
end
|
||||
end
|
||||
|
||||
should "return posts for the ordfav:<name> metatag" do
|
||||
|
||||
Reference in New Issue
Block a user