search: add unaliased:<tag> metatag.
* Add unaliased:<tag> metatag. This allows you to search for a tag without applying aliases. This is mainly useful for debugging purposes and for searching for large tags that are in the process of being aliased but haven't had all their posts moved yet. * Remove the "raw" url param from the posts index page. The "raw" param also caused the search to ignore aliases, but it was undocumented and exploitable. It was possible to use the raw param to view private favorites since favorites are treated like a hidden tag.
This commit is contained in:
@@ -10,7 +10,7 @@ class PostsController < ApplicationController
|
||||
end
|
||||
else
|
||||
tag_query = params[:tags] || params.dig(:post, :tags)
|
||||
@post_set = PostSets::Post.new(tag_query, params[:page], params[:limit], raw: params[:raw], random: params[:random], format: params[:format])
|
||||
@post_set = PostSets::Post.new(tag_query, params[:page], params[:limit], random: params[:random], format: params[:format])
|
||||
@posts = authorize @post_set.posts, policy_class: PostPolicy
|
||||
respond_with(@posts) do |format|
|
||||
format.atom
|
||||
|
||||
@@ -24,6 +24,7 @@ class PostQueryBuilder
|
||||
ordpool note comment commentary id rating locked source status filetype
|
||||
disapproved parent child search embedded md5 width height mpixels ratio
|
||||
score favcount filesize date age order limit tagcount pixiv_id pixiv
|
||||
unaliased
|
||||
] + COUNT_METATAGS + COUNT_METATAG_SYNONYMS + CATEGORY_COUNT_METATAGS
|
||||
|
||||
ORDER_METATAGS = %w[
|
||||
@@ -157,6 +158,8 @@ class PostQueryBuilder
|
||||
favorites_include(value)
|
||||
when "ordfav"
|
||||
ordfav_matches(value)
|
||||
when "unaliased"
|
||||
unaliased_matches(value)
|
||||
when "user"
|
||||
user_matches(:uploader, value)
|
||||
when "approver"
|
||||
@@ -198,6 +201,15 @@ class PostQueryBuilder
|
||||
Post.where("posts.tag_index @@ to_tsquery('danbooru', E?)", query)
|
||||
end
|
||||
|
||||
def unaliased_matches(tag)
|
||||
# don't let users use unaliased:fav:1 to view private favorites
|
||||
if tag =~ /\Afav:\d+\z/
|
||||
Post.none
|
||||
else
|
||||
tags_include(tag)
|
||||
end
|
||||
end
|
||||
|
||||
def attribute_matches(value, field, type = :integer)
|
||||
operator, *args = parse_metatag_value(value, type)
|
||||
Post.where_operator(field, operator, *args)
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
module PostSets
|
||||
class Post
|
||||
MAX_PER_PAGE = 200
|
||||
attr_reader :page, :raw, :random, :post_count, :format, :tag_string, :query
|
||||
attr_reader :page, :random, :post_count, :format, :tag_string, :query
|
||||
|
||||
def initialize(tags, page = 1, per_page = nil, raw: false, random: false, format: "html")
|
||||
def initialize(tags, page = 1, per_page = nil, random: false, format: "html")
|
||||
@query = PostQueryBuilder.new(tags)
|
||||
@tag_string = tags
|
||||
@page = page
|
||||
@per_page = per_page
|
||||
@raw = raw.to_s.truthy?
|
||||
@random = random.to_s.truthy?
|
||||
@format = format.to_s
|
||||
end
|
||||
@@ -101,8 +100,6 @@ module PostSets
|
||||
|
||||
if is_random?
|
||||
temp = get_random_posts
|
||||
elsif raw
|
||||
temp = ::Post.raw_tag_match(tag_string).order("posts.id DESC").where("true /* PostSets::Post#posts:1 */").paginate(page, :count => post_count, :limit => per_page)
|
||||
else
|
||||
temp = ::Post.tag_match(tag_string).where("true /* PostSets::Post#posts:2 */").paginate(page, :count => post_count, :limit => per_page)
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ class PostPresenter
|
||||
return "<em>none</em>".html_safe
|
||||
end
|
||||
|
||||
if !options[:show_deleted] && post.is_deleted? && options[:tags] !~ /status:(?:all|any|deleted|banned)/ && !options[:raw]
|
||||
if !options[:show_deleted] && post.is_deleted? && options[:tags] !~ /status:(?:all|any|deleted|banned)/
|
||||
return ""
|
||||
end
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ module PostSetPresenters
|
||||
end
|
||||
|
||||
posts.each do |post|
|
||||
html << PostPresenter.preview(post, options.merge(:tags => @post_set.tag_string, :raw => @post_set.raw))
|
||||
html << PostPresenter.preview(post, options.merge(:tags => @post_set.tag_string))
|
||||
html << "\n"
|
||||
end
|
||||
|
||||
@@ -19,7 +19,7 @@ module PostSetPresenters
|
||||
end
|
||||
|
||||
def not_shown(post, options)
|
||||
!options[:show_deleted] && post.is_deleted? && @post_set.tag_string !~ /status:(?:all|any|deleted|banned)/ && !@post_set.raw
|
||||
!options[:show_deleted] && post.is_deleted? && @post_set.tag_string !~ /status:(?:all|any|deleted|banned)/
|
||||
end
|
||||
|
||||
def none_shown(options)
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
<section id="search-box">
|
||||
<h1>Search</h1>
|
||||
<%= form_tag(path, method: "get", id: "search-box-form") do %>
|
||||
<% if params[:raw] %>
|
||||
<%= hidden_field_tag :raw, params[:raw] %>
|
||||
<% end %>
|
||||
<% if params[:random] %>
|
||||
<%= hidden_field_tag :random, params[:random] %>
|
||||
<% end %>
|
||||
|
||||
@@ -951,6 +951,19 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
||||
assert_tag_match([post], "filesize:1048576b")
|
||||
end
|
||||
|
||||
should "return posts for an unaliased:<tag> search" do
|
||||
post = create(:post, tag_string: "gray_eyes fav:self")
|
||||
create(:tag_alias, antecedent_name: "gray_eyes", consequent_name: "grey_eyes")
|
||||
|
||||
assert_tag_match([], "gray_eyes")
|
||||
assert_tag_match([post], "-gray_eyes")
|
||||
|
||||
assert_tag_match([post], "unaliased:gray_eyes")
|
||||
assert_tag_match([], "-unaliased:gray_eyes")
|
||||
|
||||
assert_tag_match([], "unaliased:fav:#{CurrentUser.id}")
|
||||
end
|
||||
|
||||
should "not perform fuzzy matching for an exact filesize search" do
|
||||
post = create(:post, file_size: 1.megabyte)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user