From a12f6badde9fe78481b89a0c98ff6487b2808bd2 Mon Sep 17 00:00:00 2001 From: Albert Yi Date: Wed, 17 Apr 2019 12:00:19 -0700 Subject: [PATCH] add `RequestStore` gem, support universal `only` param for api endpoints (fixes #4068) --- Gemfile | 1 + Gemfile.lock | 3 +++ app/controllers/application_controller.rb | 7 ++++++ app/controllers/post_versions_controller.rb | 2 +- app/controllers/posts_controller.rb | 2 +- app/models/application_record.rb | 25 +++++++++++++++++++++ 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 8b48e6c30..3871d4f9c 100644 --- a/Gemfile +++ b/Gemfile @@ -52,6 +52,7 @@ gem 'jquery-rails' gem 'webpacker', '>= 4.0.x' gem 'retriable' gem 'redis' +gem 'request_store' # needed for looser jpeg header compat gem 'ruby-imagespec', :require => "image_spec", :git => "https://github.com/r888888888/ruby-imagespec.git", :branch => "exif-fixes" diff --git a/Gemfile.lock b/Gemfile.lock index 8c6ba7242..f66d857b2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -319,6 +319,8 @@ GEM ref (2.0.0) representable (2.3.0) uber (~> 0.0.7) + request_store (1.4.1) + rack (>= 1.4) responders (2.4.0) actionpack (>= 4.2.0, < 5.3) railties (>= 4.2.0, < 5.3) @@ -492,6 +494,7 @@ DEPENDENCIES rakismet recaptcha redis + request_store responders retriable ruby-imagespec! diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 163565ab8..291adbe46 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,6 +10,7 @@ class ApplicationController < ActionController::Base before_action :api_check before_action :set_safe_mode before_action :set_variant + before_action :track_only_param # before_action :secure_cookies_check layout "default" helper_method :show_moderation_notice? @@ -48,6 +49,12 @@ class ApplicationController < ActionController::Base end end + def track_only_param + if params[:only] + RequestStore[:only_param] = params[:only].split(/,/) + end + end + def api_check if !CurrentUser.is_anonymous? && !request.get? && !request.head? if CurrentUser.user.token_bucket.nil? diff --git a/app/controllers/post_versions_controller.rb b/app/controllers/post_versions_controller.rb index 0bcce0418..559a9b2a9 100644 --- a/app/controllers/post_versions_controller.rb +++ b/app/controllers/post_versions_controller.rb @@ -7,7 +7,7 @@ class PostVersionsController < ApplicationController @post_versions = PostArchive.includes(:updater, post: [:versions]).search(search_params).paginate(params[:page], :limit => params[:limit], :search_count => params[:search]) respond_with(@post_versions) do |format| format.xml do - render :xml => @post_versions.to_xml(:root => "post-versions") + render xml: @post_versions.to_xml(root: "post-versions") end end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 96eb0bfd7..c69cb898b 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -14,7 +14,7 @@ class PostsController < ApplicationController respond_with(@posts) do |format| format.atom format.xml do - render :xml => @posts.to_xml(:root => "posts") + render xml: @posts.to_xml(root: "posts") end end end diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 36e1e6879..62298b121 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -149,12 +149,25 @@ class ApplicationRecord < ActiveRecord::Base def as_json(options = {}) options ||= {} + options[:except] ||= [] options[:except] += hidden_attributes options[:methods] ||= [] options[:methods] += method_attributes + if !options.key?(:only) && RequestStore.exist?(:only_param) + options[:only] = RequestStore[:only_param] + end + + if options[:only].is_a?(String) + options[:only] = options[:only].split(/,/) + end + + if options[:only] + options[:methods] = options[:methods] & options[:only] + end + super(options) end @@ -167,6 +180,18 @@ class ApplicationRecord < ActiveRecord::Base options[:methods] ||= [] options[:methods] += method_attributes + if !options.key?(:only) && RequestStore.exist?(:only_param) + options[:only] = RequestStore[:only_param] + end + + if options[:only].is_a?(String) + options[:only] = options[:only].split(/,/) + end + + if options[:only] + options[:methods] = options[:methods] & options[:only] + end + super(options, &block) end