stffn/declarative_authorization

Rails 4 - strong parameters

bhopwood opened this issue · 7 comments

I'm looking to use declarative_authorization with a new rails 4 app, but there seems to be an issue causing a 'ActiveModel::ForbiddenAttributesError' on 'create'.
Is there a known fix or is anyone working on one ?

Any help with the Rails 4 compatibility is appreciated. I currently don't have spare time for it.

In the mean time you should be able to just overwrite the method declarative_authorization crates for you. Something like...

private

def new_foo_from_params
  @foo = Foo.new(foo_params)
end

def foo_params
  params[:work_period].permit(:name, :title, :date)
end

works great, but gives ActionController::ParameterMissing for new action.

zeiv commented

I've got filter_resource_access working on my Rails 4 app with that commit. Since the strong_parameters method is private by default, you'll need to define your own instance variables in your controller for :new and :create actions rather than rely on the "auto-generated" ones from filter_resource_access.

I also haven't been able to get load_object from ControllerPermission in in_controller.rb to get the instance variable from the controller causing extra problems for :new actions. Does anyone know why this might happen or if this is some new "feature" of Rails 4?

Anyway everything is working in my Rails 4 app now. I'll submit a pull request in a bit.

Hi Zeiv, did you get any further on this? Also wondering if you can clarify what you did to get it working in relation to the instance variables?

zeiv commented

Not much more than what you have unfortunately, but I'll push my most recent commits so you can take a look. In that load_object method contr.instance_variable_get(instance_var) returns nil, so I changed the next (and final) object loading strategy to find_or_initialize_by :id instead of find(params[:id]) so that an object for the controller is returned even on new actions by looking at the params. Of course, this assumes that the object instance variable in your new action contains nil attributes (which by default is true in Rails), so it's not an ideal solution.

Adding puts contr.instance_variables.inspect in the code for debugging doesn't return an object-containing instance variable in ANY of the tests on Rails 4.

Also, I've open-sourced the Rails 4 app that I've been trying to get declarative_authorization working with, if that helps: https://github.com/zeiv/udjournal. The problems I were encountering in that app ARE fixed now, but I'm still not satisfied with the test coverage I've added to declarative_authorization for Rails 4 compatibility, so I'm going to hold off on that pull request for a bit longer.

EDIT: Another major problem with my progress so far is that for some reason I can't get the :strong_parameters option for filter_resource_access to trickle down to ControllerPermission.load_object when debugging the new tests I added for Rails 4 at the end of controller_filter_resource_access_test.rb. Can anyone spot what I'm missing here? Theoretically, it's supposed to come in from filter_resource_access then get passed to filter_access_to around line 292, which then gets passed into ControllerPermission.new about line 317. Do I need to pass the option into load_object as a method parameter since it is a private method?

zeiv commented

From the in_controller.rb source comments: "filter_resource_access creates a new object from company parameters: Company.new(params[:company]."

After spending countless hours trying to get this working with strong_parameters, I've come to the realization that this behaviour is precisely the what strong_parameters is trying to prevent! I've disable the "feature" when the :strong_parameters option on filter_resource_access is true and automatically skipped attribute_check for the :create action.
Problem solved! 🎉