Skip to content

Commit

Permalink
BREAKING CHANGE: Stop authorization adapters assigning attributes on …
Browse files Browse the repository at this point in the history
…create and update, just check for permission instead

Newly created object still gets attributes assigned.
Closes #3120
  • Loading branch information
mshibuya committed Jul 21, 2019
1 parent 70a00b0 commit c84d170
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 8 deletions.
4 changes: 1 addition & 3 deletions lib/rails_admin/config/actions/edit.rb
Expand Up @@ -25,9 +25,7 @@ class Edit < RailsAdmin::Config::Actions::Base
sanitize_params_for!(request.xhr? ? :modal : :update)

@object.set_attributes(params[@abstract_model.param_key])
@authorization_adapter && @authorization_adapter.attributes_for(:update, @abstract_model).each do |name, value|
@object.send("#{name}=", value)
end
@authorization_adapter && @authorization_adapter.authorize(:update, @abstract_model, @object)
changes = @object.changes
if @object.save
@auditing_adapter && @auditing_adapter.update_object(@object, @abstract_model, _current_user, changes)
Expand Down
4 changes: 1 addition & 3 deletions lib/rails_admin/config/actions/new.rb
Expand Up @@ -36,9 +36,7 @@ class New < RailsAdmin::Config::Actions::Base
sanitize_params_for!(request.xhr? ? :modal : :create)

@object.set_attributes(params[@abstract_model.param_key])
@authorization_adapter && @authorization_adapter.attributes_for(:create, @abstract_model).each do |name, value|
@object.send("#{name}=", value)
end
@authorization_adapter && @authorization_adapter.authorize(:create, @abstract_model, @object)

if @object.save
@auditing_adapter && @auditing_adapter.create_object(@object, @abstract_model, _current_user)
Expand Down
14 changes: 14 additions & 0 deletions spec/integration/authorization/cancancan_spec.rb
Expand Up @@ -132,6 +132,13 @@ def initialize(user)
expect(@player).to be_suspended # suspended is inherited behavior based on permission
end

it 'POST /admin/player/new with unauthorized attribute value should raise access denied' do
visit new_path(model_name: 'player')
fill_in 'player[name]', with: 'Jackie Robinson'
uncheck 'player[suspended]'
expect { click_button 'Save' }.to raise_error(CanCan::AccessDenied)
end

it 'GET /admin/player/1/edit should raise access denied' do
@player = FactoryBot.create :player
expect { visit edit_path(model_name: 'player', id: @player.id) }.to raise_error(CanCan::AccessDenied)
Expand Down Expand Up @@ -163,6 +170,13 @@ def initialize(user)
expect { visit edit_path(model_name: 'player', id: @player.id) }.to raise_error(CanCan::AccessDenied)
end

it 'PUT /admin/player/new with unauthorized attribute value should raise access denied' do
@player = FactoryBot.create :player
visit edit_path(model_name: 'player', id: @player.id)
check 'player[retired]'
expect { click_button 'Save' }.to raise_error(CanCan::AccessDenied)
end

it 'GET /admin/player/1/delete should raise access denied' do
@player = FactoryBot.create :player
expect { visit delete_path(model_name: 'player', id: @player.id) }.to raise_error(CanCan::AccessDenied)
Expand Down
26 changes: 26 additions & 0 deletions spec/integration/authorization/pundit_spec.rb
Expand Up @@ -97,6 +97,32 @@
end
end

describe 'with create and read player role' do
before do
@user.update(roles: [:admin, :read_player, :create_player])
end

it 'POST /admin/player/new with unauthorized attribute value should raise access denied' do
visit new_path(model_name: 'player')
fill_in 'player[name]', with: 'Jackie Robinson'
uncheck 'player[suspended]'
expect { click_button 'Save' }.to raise_error(Pundit::NotAuthorizedError)
end
end

describe 'with update and read player role' do
before do
@user.update(roles: [:admin, :read_player, :update_player])
end

it 'PUT /admin/player/new with unauthorized attribute value should raise access denied' do
@player = FactoryBot.create :player
visit edit_path(model_name: 'player', id: @player.id)
check 'player[retired]'
expect { click_button 'Save' }.to raise_error(Pundit::NotAuthorizedError)
end
end

context 'when ApplicationController already has pundit_user' do
let(:admin) { FactoryBot.create :user, roles: [:admin] }
before do
Expand Down
10 changes: 8 additions & 2 deletions spec/policies.rb
Expand Up @@ -33,10 +33,12 @@ def index?
def new?
user.roles.include? :admin
end
alias create? new?

def edit?
user.roles.include? :admin
end
alias update? edit?

def export?
user.roles.include? :admin
Expand All @@ -49,12 +51,16 @@ def rails_admin_index?

class PlayerPolicy < ApplicationPolicy
def new?
(user.roles.include?(:create_player) || user.roles.include?(:admin) || user.roles.include?(:manage_player))
(user.roles.include?(:manage_player) ||
(user.roles.include?(:create_player) && (!record.is_a?(Player) || record.suspended)))
end
alias create? new?

def edit?
(user.roles.include? :manage_player)
(user.roles.include?(:manage_player) ||
(user.roles.include?(:update_player) && (!record.is_a?(Player) || !record.retired)))
end
alias update? edit?

def destroy?
(user.roles.include? :manage_player)
Expand Down

0 comments on commit c84d170

Please sign in to comment.