ActiveAdmin检查创建授权

时间:2017-12-13 15:37:55

标签: ruby-on-rails activeadmin cancancan

对我而言,似乎ActiveAdmin应该主要在两种情况下检查创建授权:

  • UI需要显示“创建新票证”按钮:此处,检查current_user是否有权创建通用票证是很有用的。

    Cancancan语法如下所示:

    user.can?(:create, Ticket)
    
  • ActiveAdmin需要了解资源是否可以在表单提交后实际存储在数据库中:此处检查当前用户是否可以使用票证“输入”值来存储该票证是否有用形成。

    Cancancan语法如下所示:

     user.can?(:create, Ticket.new({author_id: user.id, some: "x", other: "y", values: "z"}))
    

就是这样!那么为什么ActiveAdmin会在为用户显示生成的“创建表单”之前检查以下内容?

user.can?(:create, Ticket.new({author_id: nil, some: nil, other: nil, values: nil}))

如果当前用户仅拥有创建author_id = own_user_id

的票证的权限,该怎么办?

即使在查看表单之前,授权也会失败。

2 个答案:

答案 0 :(得分:0)

我无法解释为什么ActiveAdmin是以这种方式编写的,但我可以告诉你我是如何解决类似问题的。

首先,您需要授予您的用户ability以在所有条件下创建所需的记录:

# app/models/ability.rb
...
  can :create, Ticket
...

这将获得您过去的ActiveAdmin can?检查,并允许用户查看表单。但我们需要确保author_id属于当前用户。为此,您可以在保存之前使用before_create回调设置正确的author_id

# app/admin/ticket.rb
ActiveAdmin.register Ticket do
...
  before_create do |ticket|
    ticket.author_id = own_user_id
  end
...
end

以上假设您有一个辅助方法或一个名为own_user_id的变量,可供ActiveAdmin模块使用并返回正确的用户ID。如果您使用的是Devise,则可以将current_user.id替换为own_user_id

我承认,这不是最干净的解决方案,但它确实有效。我在自己的项目中实现了类似的东西。

答案 1 :(得分:0)

我确实按如下方式覆盖了数据访问类,以使其正常工作。

我:

  • 禁用我觉得在错误的时间完成的授权
  • 在保存资源之前授权之前强制验证

    ActiveAdmin::ResourceController::DataAccess.module_eval do
      def build_resource
        get_resource_ivar || begin
          resource = build_new_resource
            resource = apply_decorations(resource)
          run_build_callbacks resource
    
          # this authorization check is the one we don't need anymore
          # authorize_resource! resource
    
          set_resource_ivar resource
        end
      end
    end
    
    ActiveAdmin::ResourceController::DataAccess.module_eval do
      def save_resource(object)
        run_save_callbacks object do
          return false unless object.validate # added it
          authorize_resource! resource        # added it
          object.save(validate: false)        # disabled validation since i do it 2 lines up
        end
      end
    end