【问题标题】:How to authorize namespace, model-less controllers using CanCanCan?如何使用 CanCanCan 授权命名空间、无模型控制器?
【发布时间】:2016-12-11 07:59:15
【问题描述】:

使用 CanCanCan 授权和检查命名空间、无模型控制器的能力的正确方法是什么?

经过大量谷歌搜索和阅读 wiki,我目前拥有

#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 %>

这未正确授权控制器。管理员可以看到条件创建表单,但无权发布到创建操作。

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."

在一个示例中,wiki 建议为命名空间控制器创建一个单独的 Ability 类。 https://github.com/CanCanCommunity/cancancan/wiki/Admin-Namespace

有没有更简单的方法来实现这一点?这个应用程序使用了许多命名空间的控制器,我真的不想为每个控制器创建一个能力类。

是否有正确的语法来引用 Ability 类中的命名空间控制器?

can [:create], Namespaces::Unattacheds
can [:create], :namespaces_unattacheds
can [:create], namespaces/unattacheds
????

【问题讨论】:

  • Namespaces::UnattachedsController 是一个类,而不是一个定义,我认为。

标签: ruby-on-rails cancan cancancan


【解决方案1】:

听起来您正在为 Namespaces::Unattacheds 模型设置权限,这意味着您的控制器不需要这样做:

authorize_resource class: false

您的控制器确实有一个模型。也许它也继承自 ApplicationController? (这将是合乎逻辑的事情。)

如果您试图避免影响某些控制器方法,请使用only/except 子句,如下所述: https://github.com/CanCanCommunity/cancancan/wiki/Authorizing-controller-actions#choosing-actions

如果命名空间深度在您的模型和控制器之间匹配,我认为它不是问题。您只需要load_and_authorize_resourceability.rb 中的正确形式:

can [:create], Namespaces::Unattacheds

【讨论】:

  • 谢谢。有几个控制器引用相同的模型 - 用户。但是每个控制器都有不同的关联权限。因此,我认为不能为用户定义能力。我需要一种方法来定义控制器的权限
  • 所有控制器的can 语句应属于同一能力类。它应该根据模型描述完整的可用操作集,而不管当前控制器是什么。这意味着您可能需要像 can :create, SomeClass if admin? 这样的语句。将其视为以控制器为中心是 CanCan 的反模式。
  • 使用 CanCan,您将如何仅授权管理员批准/拒绝用户(更新操作),而仅授权用户更新自己的属性,而不偏离 CRUD 控制器格式?
  • 您关心的是允许管理员只更新批准/拒绝组件而不是其他属性?从 cancan 的角度来看,您可能会在 ApproveRejectActionbelongs_to :user 的单独模型的情况下进行不同的建模。然后can :create, ApproveRejectAction if admin?can :update, User, id: current_user.id
【解决方案2】:

也许不是最漂亮的解决方案,但我设法通过添加

skip_authorization_check
before_action { raise CanCan::AccessDenied unless current_user.can?(params[:action].to_sym, ::namespaces_unattacheds) }

如果你这样做,你可以从这个控制器传递你想要的任何东西到技能类。

你需要加罐子吗?方法首先能够使用这个https://github.com/CanCanCommunity/cancancan/wiki/Ability-for-Other-Users

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多