From d2ff617cd3fdc9a039d7071b010dc1332aae4fcf Mon Sep 17 00:00:00 2001 From: Radan Skoric Date: Wed, 18 Mar 2015 15:50:06 +0100 Subject: [PATCH] Add `pundit_policy_authorized?` and `pundit_policy_scoped?` methods In some cases we might need to simply check if `authorize` or `policy_scope` were called, without immediately raising and exception. In other cases we might be happy if either was called and only want to raise if neither was called. All those edge cases are most easily served by exposing lower level function which just perform the checks and return `true` or `false`. The `verify_*` methods can then build on top of them to offer a convenient path for the most common use cases. --- CHANGELOG.md | 1 + README.md | 7 ++++++- lib/pundit.rb | 12 ++++++++++-- spec/pundit_spec.rb | 22 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51c780d..b0b4dc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Caches policy scopes and policies. - Explicitly setting the policy for the controller via `controller.policy = foo` has been removed. Instead use `controller.policies[record] = foo`. - Explicitly setting the policy scope for the controller via `controller.policy_policy = foo` has been removed. Instead use `controller.policy_scopes[scope] = foo`. +- Add `pundit_policy_authorized?` and `pundit_policy_scoped?` methods. ## 0.3.0 (2014-08-22) diff --git a/README.md b/README.md index c178cbe..5b0a6c8 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ end ``` Likewise, Pundit also adds `verify_policy_scoped` to your controller. This -will raise an exception in the vein of `verify_authorized`. However it tracks +will raise an exception in the vein of `verify_authorized`. However, it tracks if `policy_scope` is used instead of `authorize`. This is mostly useful for controller actions like `index` which find collections with a scope and don't authorize individual instances. @@ -204,6 +204,11 @@ def show end ``` +If you need to perform some more sophisticated logic or you want to raise a custom +exception you can use the two lower level methods `pundit_policy_authorized?` +and `pundit_policy_scoped?` which return `true` or `false` depending on whether +`authorize` or `policy_scope` have been called, respectively. + ## Scopes Often, you will want to have some kind of view listing records which a diff --git a/lib/pundit.rb b/lib/pundit.rb index e254a16..2bf0171 100644 --- a/lib/pundit.rb +++ b/lib/pundit.rb @@ -84,12 +84,20 @@ module Pundit end end + def pundit_policy_authorized? + !!@_pundit_policy_authorized + end + + def pundit_policy_scoped? + !!@_pundit_policy_scoped + end + def verify_authorized - raise AuthorizationNotPerformedError unless @_pundit_policy_authorized + raise AuthorizationNotPerformedError unless pundit_policy_authorized? end def verify_policy_scoped - raise PolicyScopingNotPerformedError unless @_pundit_policy_scoped + raise PolicyScopingNotPerformedError unless pundit_policy_scoped? end def authorize(record, query=nil) diff --git a/spec/pundit_spec.rb b/spec/pundit_spec.rb index 04cecca..ebff539 100644 --- a/spec/pundit_spec.rb +++ b/spec/pundit_spec.rb @@ -224,6 +224,28 @@ describe Pundit do end end + describe "#pundit_policy_authorized?" do + it "is true when authorized" do + controller.authorize(post) + expect(controller.pundit_policy_authorized?).to be true + end + + it "is false when not authorized" do + expect(controller.pundit_policy_authorized?).to be false + end + end + + describe "#pundit_policy_scoped?" do + it "is true when policy_scope is used" do + controller.policy_scope(Post) + expect(controller.pundit_policy_scoped?).to be true + end + + it "is false when policy scope is not used" do + expect(controller.pundit_policy_scoped?).to be false + end + end + describe "#authorize" do it "infers the policy name and authorizes based on it" do expect(controller.authorize(post)).to be_truthy