问题
What is the correct way to authorize and check abilities for a namespaced, model-less controller using CanCanCan?
After much googling and reading the wiki, I currently have
#controllers/namespaces/unattacheds_controller.rb
def Namespaces::UnattachedsController
authorize_resource class: false
def create
# does some stuff
end
end
#models/ability.rb
def admin
can [:create], :namespaces_unattacheds
end
#view/
<%= if can? :create, :namespaces_unattacheds %>
# show a create form to authorized users
<% end %>
This is not correctly authorizing the controller. Admins can see the conditional create form, but are not authorized to post to the create action.
post :create, valid_params
Failure/Error: { it { expect( flash ).to have_content "Successfully created" }
expected to find text "Successfully created"
got: "You are not authorized to access this page."
In one example, the wiki suggests creating a separate Ability class for a namespaced controller. https://github.com/CanCanCommunity/cancancan/wiki/Admin-Namespace
Is there a simpler way to achieve this? This app uses many namespaced controllers, I don't really want to create an ability class for each one.
Is there correct syntax to refer to the namespaced controller in the Ability class?
can [:create], Namespaces::Unattacheds
can [:create], :namespaces_unattacheds
can [:create], namespaces/unattacheds
????
回答1:
It sounds like you are setting permissions on the Namespaces::Unattacheds
model, which means your controller doesn't need to do:
authorize_resource class: false
Your controller does have a model. Maybe it also inherits from ApplicationController? (That would be a logical thing to do.)
If you are trying to avoid affecting certain controller methods, use only
/except
clauses, as described here:
https://github.com/CanCanCommunity/cancancan/wiki/Authorizing-controller-actions#choosing-actions
I don't think the namespace depth is an issue IF it matches between your model and your controller. You just need load_and_authorize_resource
and the proper form in ability.rb
:
can [:create], Namespaces::Unattacheds
回答2:
Maybe not the prettiest solution but I managed to achive this by adding
skip_authorization_check
before_action { raise CanCan::AccessDenied unless current_user.can?(params[:action].to_sym, ::namespaces_unattacheds) }
If you do it like this, you can pass whatever you want from this controller to the ability class.
You need to add the can? method first to be able to use this https://github.com/CanCanCommunity/cancancan/wiki/Ability-for-Other-Users
来源:https://stackoverflow.com/questions/41084104/how-to-authorize-namespace-model-less-controllers-using-cancancan