Skip to content

Commit

Permalink
Support default Pundint policy class.
Browse files Browse the repository at this point in the history
basic form @seban on #3323, with changes from @timoschilling
  • Loading branch information
Sebastian Nowak authored and timoschilling committed Nov 3, 2014
1 parent 46e923e commit c93f6f4
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
25 changes: 25 additions & 0 deletions lib/active_admin/pundit_adapter.rb
Expand Up @@ -2,6 +2,9 @@

require 'pundit'

# Add a setting to the application to configure the pundit default policy
ActiveAdmin::Application.inheritable_setting :pundit_default_policy, nil

module ActiveAdmin

class PunditAdapter < AuthorizationAdapter
Expand All @@ -17,6 +20,12 @@ def scope_collection(collection, action = Auth::READ)
# scoping is appliable only to read/index action
# which means there is no way how to scope other actions
Pundit.policy_scope!(user, collection)
rescue Pundit::NotDefinedError => e
if default_policy_class && default_policy_class.const_defined?(:Scope)
default_policy_class::Scope.new(user, collection).resolve
else
raise e
end
end

def retrieve_policy(subject)
Expand All @@ -25,6 +34,12 @@ def retrieve_policy(subject)
when Class then Pundit.policy!(user, subject.new)
else Pundit.policy!(user, subject)
end
rescue Pundit::NotDefinedError => e
if default_policy_class
default_policy(user, subject)
else
raise e
end
end

def format_action(action, subject)
Expand All @@ -38,6 +53,16 @@ def format_action(action, subject)
end
end

private

def default_policy_class
ActiveAdmin.application.pundit_default_policy && ActiveAdmin.application.pundit_default_policy.constantize
end

def default_policy(user, subject)
default_policy_class.new(user, subject)
end

end

end
Expand Up @@ -65,6 +65,11 @@ ActiveAdmin.setup do |config|
# CanCanAdapter or make your own. Please refer to documentation.
# config.authorization_adapter = ActiveAdmin::CanCanAdapter

# In case you prefer Pundit over other solutions you can here pass
# the name of default policy class. This policy will be used in every
# case when Pundit is unable to find suitable policy.
# config.pundit_default_policy = "MyDefaultPunditPolicy"

# You can customize your CanCan Ability class name here.
# config.cancan_ability_class = "Ability"

Expand Down
43 changes: 43 additions & 0 deletions spec/unit/pundit_adapter_spec.rb
@@ -1,5 +1,21 @@
require 'rails_helper'

class DefaultPolicy < ApplicationPolicy
class Scope

attr_reader :user, :scope

def initialize(user, scope)
@user = user
@scope = scope
end

def resolve
scope
end
end
end

describe ActiveAdmin::PunditAdapter do

describe "full integration" do
Expand All @@ -8,6 +24,8 @@
let(:namespace) { ActiveAdmin::Namespace.new(application, "Admin") }
let(:resource) { namespace.register(Post) }
let(:auth) { namespace.authorization_adapter.new(resource, double) }
let(:default_policy_klass) { DefaultPolicy }
let(:default_policy_klass_name) { "DefaultPolicy" }

before do
namespace.authorization_adapter = ActiveAdmin::PunditAdapter
Expand All @@ -31,6 +49,31 @@ def resolve
auth.scope_collection(collection, :read)
expect(collection).to eq collection
end

context 'when Pundit is unable to find policy scope' do
let(:collection) { double("collection", to_sym: :collection) }
subject(:scope) { auth.scope_collection(collection, :read) }

before do
allow(ActiveAdmin.application).to receive(:pundit_default_policy).and_return default_policy_klass_name
allow(Pundit).to receive(:policy_scope!) { raise Pundit::NotDefinedError.new }
end

it("should return default policy's scope if defined") { is_expected.to eq(collection) }
end

context "when Pundit is unable to find policy" do
let(:record) { double }

subject(:policy) { auth.retrieve_policy(record) }

before do
allow(ActiveAdmin.application).to receive(:pundit_default_policy).and_return default_policy_klass_name
allow(Pundit).to receive(:policy!) { raise Pundit::NotDefinedError.new }
end

it("should return default policy instance") { is_expected.to be_instance_of(default_policy_klass) }
end
end

end

0 comments on commit c93f6f4

Please sign in to comment.