From 2cbe4d36724a3e6b2589d0d712629de5d8f523cf Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 30 Apr 2020 12:14:28 -0500 Subject: [PATCH] search: add unaliased: metatag. * Add unaliased: 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. --- app/controllers/posts_controller.rb | 2 +- app/logical/post_query_builder.rb | 12 ++++++++++++ app/logical/post_sets/post.rb | 7 ++----- app/presenters/post_presenter.rb | 2 +- app/presenters/post_set_presenters/base.rb | 4 ++-- app/views/posts/partials/common/_search.html.erb | 3 --- test/unit/post_query_builder_test.rb | 13 +++++++++++++ 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 738caa180..9d8224b7c 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -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 diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index 7baaf62df..85f2ef008 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -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) diff --git a/app/logical/post_sets/post.rb b/app/logical/post_sets/post.rb index ea67abc4c..d757c9bf4 100644 --- a/app/logical/post_sets/post.rb +++ b/app/logical/post_sets/post.rb @@ -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 diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb index 6981e7b1d..1e0097094 100644 --- a/app/presenters/post_presenter.rb +++ b/app/presenters/post_presenter.rb @@ -7,7 +7,7 @@ class PostPresenter return "none".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 diff --git a/app/presenters/post_set_presenters/base.rb b/app/presenters/post_set_presenters/base.rb index 1a76c8b42..c99c8cbbb 100644 --- a/app/presenters/post_set_presenters/base.rb +++ b/app/presenters/post_set_presenters/base.rb @@ -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) diff --git a/app/views/posts/partials/common/_search.html.erb b/app/views/posts/partials/common/_search.html.erb index 078d17f0a..08fc1de6f 100644 --- a/app/views/posts/partials/common/_search.html.erb +++ b/app/views/posts/partials/common/_search.html.erb @@ -3,9 +3,6 @@