How to authorize namespace, model-less controllers using CanCanCan?

£可爱£侵袭症+ 提交于 2021-01-29 04:34:15

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!