Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include conditions in AccessDenied exception #482

Merged
merged 8 commits into from
Mar 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Lint/AmbiguousBlockAssociation:


AllCops:
TargetRubyVersion: 2.0
TargetRubyVersion: 2.2.0
Exclude:
- 'gemfiles/vendor/bundle/**/*'
- 'Appraisals'
Expand Down
17 changes: 9 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ language: ruby
cache: bundler
sudo: false
rvm:
- 2.2.0
- 2.2.7
- 2.3.4
- 2.4.1
- 2.2.8
- 2.3.5
- 2.4.2
- 2.5.0
- jruby-9.0.5.0
- jruby-9.1.8.0
- jruby-9.1.9.0
gemfile:
- gemfiles/activerecord_4.2.gemfile
- gemfiles/activerecord_5.0.2.gemfile
Expand All @@ -27,19 +27,20 @@ matrix:
gemfile: gemfiles/activerecord_5.1.0.gemfile
- rvm: jruby-9.0.5.0
gemfile: gemfiles/activerecord_5.0.2.gemfile
- rvm: jruby-9.1.8.0
- rvm: jruby-9.1.9.0
gemfile: gemfiles/activerecord_5.0.2.gemfile
- rvm: jruby-9.0.5.0
gemfile: gemfiles/activerecord_5.1.0.gemfile
- rvm: jruby-9.1.8.0
- rvm: jruby-9.1.9.0
gemfile: gemfiles/activerecord_5.1.0.gemfile
notifications:
email:
recipients:
- alessandro.rodi@renuo.ch
- josua.schmid@renuo.ch
- zora.fuchs@renuo.ch
on_success: change
on_failure: change
before_install:
- gem update --system
script:
- bundle exec rubocop && bundle exec rake
6 changes: 3 additions & 3 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ appraise 'activerecord_4.2' do

gemfile.platforms :ruby, :mswin, :mingw do
gem 'sqlite3'
gem 'pg'
gem 'pg', '~> 0.21'
end
end

Expand All @@ -27,7 +27,7 @@ appraise 'activerecord_5.0.2' do

gemfile.platforms :ruby, :mswin, :mingw do
gem 'sqlite3'
gem 'pg'
gem 'pg', '~> 0.21'
end
end

Expand All @@ -43,6 +43,6 @@ appraise 'activerecord_5.1.0' do

gemfile.platforms :ruby, :mswin, :mingw do
gem 'sqlite3'
gem 'pg'
gem 'pg', '~> 0.21'
end
end
5 changes: 5 additions & 0 deletions CHANGELOG.rdoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
Unreleased

* Feature cancancan#172 - Include conditions passed to authorize! in AccessDenied exception (kraflab)
* Removed support for dynamic finders (coorasse)

2.1.3 (Jan 16th, 2018)

* Fix compatibility with Rails 5 API (Eric-Guo)

2.1.2 (Nov 22th, 2017)

* Various bugfixes on version 2.1.0
Expand Down
2 changes: 1 addition & 1 deletion cancancan.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Gem::Specification.new do |s|
s.files = `git ls-files lib init.rb cancancan.gemspec`.split($INPUT_RECORD_SEPARATOR)
s.require_paths = ['lib']

s.required_ruby_version = '>= 2.0.0'
s.required_ruby_version = '>= 2.2.0'

s.add_development_dependency 'bundler', '~> 1.3'
s.add_development_dependency 'rubocop', '~> 0.48.1'
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/activerecord_4.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ end

platforms :ruby, :mswin, :mingw do
gem "sqlite3"
gem "pg"
gem "pg", "~> 0.21"
end

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/activerecord_5.0.2.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ end

platforms :ruby, :mswin, :mingw do
gem "sqlite3"
gem "pg"
gem "pg", "~> 0.21"
end

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/activerecord_5.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ end

platforms :ruby, :mswin, :mingw do
gem "sqlite3"
gem "pg"
gem "pg", '~> 0.21'
end

gemspec :path => "../"
2 changes: 1 addition & 1 deletion gemfiles/activerecord_5.1.0.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ end

platforms :ruby, :mswin, :mingw do
gem "sqlite3"
gem "pg"
gem "pg", "~> 0.21"
end

gemspec path: "../"
2 changes: 1 addition & 1 deletion lib/cancan/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def authorize!(action, subject, *args)
end
if cannot?(action, subject, *args)
message ||= unauthorized_message(action, subject)
raise AccessDenied.new(message, action, subject)
raise AccessDenied.new(message, action, subject, args)
end
subject
end
Expand Down
11 changes: 7 additions & 4 deletions lib/cancan/controller_additions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,12 @@ def cannot?(*args)
end
end

if defined? ActionController
%w[Base API].each do |klass|
next unless ActionController.const_defined?(klass)
ActionController.const_get(klass).class_eval { include CanCan::ControllerAdditions }
if defined? ActionController::Base
ActionController::Base.class_eval do
include CanCan::ControllerAdditions
end
elsif defined? ActionController::API
ActionController::API.class_eval do
include CanCan::ControllerAdditions
end
end
5 changes: 3 additions & 2 deletions lib/cancan/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ class AuthorizationNotPerformed < Error; end
# See ControllerAdditions#authorized! for more information on rescuing from this exception
# and customizing the message using I18n.
class AccessDenied < Error
attr_reader :action, :subject
attr_reader :action, :subject, :conditions
attr_writer :default_message

def initialize(message = nil, action = nil, subject = nil)
def initialize(message = nil, action = nil, subject = nil, conditions = nil)
@message = message
@action = action
@subject = subject
@conditions = conditions
@default_message = I18n.t(:"unauthorized.default", default: 'You are not authorized to access this page.')
end

Expand Down
2 changes: 1 addition & 1 deletion lib/cancan/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module CanCan
VERSION = '2.1.2'.freeze
VERSION = '2.1.3'.freeze
end
73 changes: 47 additions & 26 deletions spec/cancan/ability_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -424,23 +424,55 @@ class Container < Hash
expect(@ability.attributes_for(:new, Range)).to eq(foo: 'foo', bar: 123, baz: 'baz')
end

it 'raises access denied exception if ability us unauthorized to perform a certain action' do
begin
@ability.authorize! :read, :foo, 1, 2, 3, message: 'Access denied!'
rescue CanCan::AccessDenied => e
expect(e.message).to eq('Access denied!')
expect(e.action).to eq(:read)
expect(e.subject).to eq(:foo)
else
raise 'Expected CanCan::AccessDenied exception to be raised'
describe '#authorize!' do
describe 'when ability is not authorized to perform an action' do
it 'raises access denied exception' do
begin
@ability.authorize! :read, :foo, 1, 2, 3, message: 'Access denied!'
rescue CanCan::AccessDenied => e
expect(e.message).to eq('Access denied!')
expect(e.action).to eq(:read)
expect(e.subject).to eq(:foo)
expect(e.conditions).to eq([1, 2, 3])
else
raise 'Expected CanCan::AccessDenied exception to be raised'
end
end

describe 'when no extra conditions are specified' do
it 'raises access denied exception without conditions' do
begin
@ability.authorize! :read, :foo, message: 'Access denied!'
rescue CanCan::AccessDenied => e
expect(e.conditions).to eq([])
else
raise 'Expected CanCan::AccessDenied exception to be raised'
end
end
end

describe 'when no message is specified' do
it 'raises access denied exception with default message' do
begin
@ability.authorize! :read, :foo
rescue CanCan::AccessDenied => e
e.default_message = 'Access denied!'
expect(e.message).to eq('Access denied!')
else
raise 'Expected CanCan::AccessDenied exception to be raised'
end
end
end
end
end

it 'does not raise access denied exception if ability is authorized to perform an action and return subject' do
@ability.can :read, :foo
expect do
expect(@ability.authorize!(:read, :foo)).to eq(:foo)
end.to_not raise_error
describe 'when ability is authorized to perform an action' do
it 'does not raise access denied exception' do
@ability.can :read, :foo
expect do
expect(@ability.authorize!(:read, :foo)).to eq(:foo)
end.to_not raise_error
end
end
end

it 'knows when block is used in conditions' do
Expand All @@ -459,17 +491,6 @@ class Container < Hash
expect(@ability).to have_raw_sql(:read, :foo)
end

it 'raises access denied exception with default message if not specified' do
begin
@ability.authorize! :read, :foo
rescue CanCan::AccessDenied => e
e.default_message = 'Access denied!'
expect(e.message).to eq('Access denied!')
else
raise 'Expected CanCan::AccessDenied exception to be raised'
end
end

it 'determines model adapterO class by asking AbstractAdapter' do
adapter_class = double
model_class = double
Expand Down
10 changes: 6 additions & 4 deletions spec/cancan/exceptions_spec.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
require 'spec_helper'

describe CanCan::AccessDenied do
describe 'with action and subject' do
describe 'with action, subject, and conditions' do
before(:each) do
@exception = CanCan::AccessDenied.new(nil, :some_action, :some_subject)
@exception = CanCan::AccessDenied.new(nil, :some_action, :some_subject, :some_conditions)
end

it 'has action and subject accessors' do
it 'has action, subject, and conditions accessors' do
expect(@exception.action).to eq(:some_action)
expect(@exception.subject).to eq(:some_subject)
expect(@exception.conditions).to eq(:some_conditions)
end

it 'has a changable default message' do
Expand All @@ -23,9 +24,10 @@
@exception = CanCan::AccessDenied.new('Access denied!')
end

it 'has nil action and subject' do
it 'has nil action, subject, and conditions' do
expect(@exception.action).to be_nil
expect(@exception.subject).to be_nil
expect(@exception.conditions).to be_nil
end

it 'has passed message' do
Expand Down