From ba2088c6ecabd354b4b67c50bb00fccdbd1e6240 Mon Sep 17 00:00:00 2001 From: "M.Shibuya" Date: Sat, 20 Aug 2016 16:39:56 +0900 Subject: [PATCH] Introduce setup hook for authorization/auditing adapters --- app/controllers/rails_admin/application_controller.rb | 4 ---- lib/rails_admin/config.rb | 8 ++++++-- .../extensions/paper_trail/auditing_adapter.rb | 10 +++++++++- .../extensions/pundit/authorization_adapter.rb | 7 +++++++ spec/integration/authorization/pundit_spec.rb | 7 +++---- .../history/rails_admin_paper_trail_spec.rb | 7 +++++++ spec/rails_admin/config_spec.rb | 2 +- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/app/controllers/rails_admin/application_controller.rb b/app/controllers/rails_admin/application_controller.rb index 9e2178eddb..23c7510697 100644 --- a/app/controllers/rails_admin/application_controller.rb +++ b/app/controllers/rails_admin/application_controller.rb @@ -56,10 +56,6 @@ def _audit! instance_eval(&RailsAdmin::Config.audit_with) end - def user_for_paper_trail - _current_user.try(:id) || _current_user - end - rescue_from RailsAdmin::ObjectNotFound do flash[:error] = I18n.t('admin.flash.object_not_found', model: @model_name, id: params[:id]) params[:action] = 'index' diff --git a/lib/rails_admin/config.rb b/lib/rails_admin/config.rb index 1f79688646..2f185a02bb 100644 --- a/lib/rails_admin/config.rb +++ b/lib/rails_admin/config.rb @@ -110,8 +110,10 @@ def authenticate_with(&blk) def audit_with(*args, &block) extension = args.shift if extension + klass = RailsAdmin::AUDITING_ADAPTERS[extension] + klass.setup if klass.respond_to? :setup @audit = proc do - @auditing_adapter = RailsAdmin::AUDITING_ADAPTERS[extension].new(*([self] + args).compact) + @auditing_adapter = klass.new(*([self] + args).compact) end elsif block @audit = block @@ -145,8 +147,10 @@ def audit_with(*args, &block) def authorize_with(*args, &block) extension = args.shift if extension + klass = RailsAdmin::AUTHORIZATION_ADAPTERS[extension] + klass.setup if klass.respond_to? :setup @authorize = proc do - @authorization_adapter = RailsAdmin::AUTHORIZATION_ADAPTERS[extension].new(*([self] + args).compact) + @authorization_adapter = klass.new(*([self] + args).compact) end elsif block @authorize = block diff --git a/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb b/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb index 94e6e51c54..c1e15231f1 100644 --- a/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +++ b/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb @@ -38,8 +38,16 @@ class AuditingAdapter message: :event, }.freeze + def self.setup + raise('PaperTrail not found') unless defined?(::PaperTrail) + RailsAdmin::ApplicationController.class_eval do + def user_for_paper_trail + _current_user.try(:id) || _current_user + end + end + end + def initialize(controller, user_class = 'User', version_class = '::Version') - raise('PaperTrail not found') unless defined?(PaperTrail) @controller = controller @controller.send(:set_paper_trail_whodunnit) if @controller begin diff --git a/lib/rails_admin/extensions/pundit/authorization_adapter.rb b/lib/rails_admin/extensions/pundit/authorization_adapter.rb index fe76c09b8e..d1b7743a50 100644 --- a/lib/rails_admin/extensions/pundit/authorization_adapter.rb +++ b/lib/rails_admin/extensions/pundit/authorization_adapter.rb @@ -5,6 +5,13 @@ module Pundit # You can create another adapter for different authorization behavior, just be certain it # responds to each of the public methods here. class AuthorizationAdapter + # This method is called first time only and used for setup + def self.setup + RailsAdmin::ApplicationController.class_eval do + include ::Pundit + end unless RailsAdmin::ApplicationController.ancestors.include? 'Pundit' + end + # See the +authorize_with+ config method for where the initialization happens. def initialize(controller) @controller = controller diff --git a/spec/integration/authorization/pundit_spec.rb b/spec/integration/authorization/pundit_spec.rb index 18339ccd5f..69b7bb6e25 100644 --- a/spec/integration/authorization/pundit_spec.rb +++ b/spec/integration/authorization/pundit_spec.rb @@ -1,10 +1,6 @@ require 'spec_helper' describe 'RailsAdmin Pundit Authorization', type: :request do - before(:all) do - ApplicationController.send :include, ::Pundit - end - subject { page } before do @@ -104,10 +100,12 @@ context 'when ApplicationController already has pundit_user' do let(:admin) { FactoryGirl.create :user, roles: [:admin] } before do + RailsAdmin.config.parent_controller = 'ApplicationController' allow_any_instance_of(ApplicationController).to receive(:pundit_user).and_return(admin) end it 'uses original pundit_user' do + pending 'no way to dynamically change superclass' expect { visit dashboard_path }.not_to raise_error end end @@ -137,6 +135,7 @@ dashboard do authorization_key :dashboard? end + index end end end diff --git a/spec/integration/history/rails_admin_paper_trail_spec.rb b/spec/integration/history/rails_admin_paper_trail_spec.rb index 9f97c79c87..9d42c099a5 100644 --- a/spec/integration/history/rails_admin_paper_trail_spec.rb +++ b/spec/integration/history/rails_admin_paper_trail_spec.rb @@ -8,6 +8,13 @@ end end + after(:each) do + # if #user_for_paper_trail is left unused, PaperTrail complains about it + RailsAdmin::ApplicationController.class_eval do + undef user_for_paper_trail + end + end + describe 'on object creation', type: :request do subject { page } before do diff --git a/spec/rails_admin/config_spec.rb b/spec/rails_admin/config_spec.rb index 084d42c4dd..ed8af27ac4 100644 --- a/spec/rails_admin/config_spec.rb +++ b/spec/rails_admin/config_spec.rb @@ -263,7 +263,7 @@ class RecursivelyEmbedsMany describe '.parent_controller' do it 'uses default class' do - expect(RailsAdmin.config.parent_controller).to eq '::ApplicationController' + expect(RailsAdmin.config.parent_controller).to eq '::ActionController::Base' end it 'uses other class' do