From 03d01bbdc25c505ac4d637a39a9315a2f210ef17 Mon Sep 17 00:00:00 2001 From: mrloop Date: Thu, 12 Mar 2020 09:08:02 +0000 Subject: [PATCH] Better error message if authorize passed a Class In some cases you may want to authorize actions against a class not an instance of that class. If authorization fails when a class is passed to authorize the error message is unhelpful. For example not allowed to index? Class This PR checks if an instance or class was passed and provides more informative error message in the case of a class. The error message for an instance being passed remains the same. For a concrete example of class being passed see jsonapi-authorization https://github.com/venuu/jsonapi-authorization/blob/3251c6589d31bc931ee3a98c5c47e16eedd82b97/lib/jsonapi/authorization/default_pundit_authorizer.rb#L28-L31 --- lib/pundit.rb | 8 +++++++- spec/pundit_spec.rb | 10 ++++++++++ spec/spec_helper.rb | 4 ++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/pundit.rb b/lib/pundit.rb index 0b3e31a7..96acbc97 100644 --- a/lib/pundit.rb +++ b/lib/pundit.rb @@ -33,7 +33,13 @@ def initialize(options = {}) @policy = options[:policy] @reason = options[:reason] - message = options.fetch(:message) { "not allowed to #{query} this #{record.class}" } + name = if record.is_a?(Class) + record.name + else + "this #{record.class.name}" + end + + message = options.fetch(:message) { "not allowed to #{query} #{name}" } end super(message) diff --git a/spec/pundit_spec.rb b/spec/pundit_spec.rb index b07da956..72510414 100644 --- a/spec/pundit_spec.rb +++ b/spec/pundit_spec.rb @@ -484,6 +484,16 @@ it "raises an error with a invalid policy constructor" do expect { controller.authorize(wiki, :destroy?) }.to raise_error(Pundit::InvalidConstructorError) end + + it "raises an error with class name when passed Class" do + expect { controller.authorize(Post, :index?) } + .to raise_error(Pundit::NotAuthorizedError, "not allowed to index? Post") + end + + it "raises an error with class name when passed record" do + expect { controller.authorize(post, :destroy?) } + .to raise_error(Pundit::NotAuthorizedError, "not allowed to destroy? this Post") + end end describe "#skip_authorization" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4197d548..dffcfab5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -35,6 +35,10 @@ def show? true end + def index? + false + end + def permitted_attributes if post.user == user %i[title votes]