【问题标题】:What's the best approach to apply role-based access authorization in Active Admin?在 Active Admin 中应用基于角色的访问授权的最佳方法是什么?
【发布时间】:2018-11-16 09:13:43
【问题描述】:

如果只使用 ActiveAdmin,我知道我可以做这样的事情来限制某个用户组对资源的访问:

ActiveAdmin.register Resource do
  menu :parent => "Super Admin Only", :if => proc { current_admin_user.super_admin? }
end

但是,如果我有一个根据特定用户组的需要更新的动态访问/权限控制表单,我需要能够分别更新我的 ActiveAdmin。

我将我的权限数据保存为 json(键值对)。一开始我是想用ActiveAdmin::AuthorizationAdapter

class StaffAuthorization < ActiveAdmin::AuthorizationAdapter

  def authorized?(action, subject = nil)
    return true if resource.try(:name) == 'Dashboard'
    return false if action == :destroy

    retrieve_policy(action).authorized?
  end

  def role
    user.role
  end

  def policy_klass
    "policy/staff/#{role}".classify.constantize
  rescue NameError
    Policy::Staff::Default
  end

  def retrieve_policy(action)
    policy_klass.new(user, resource, action)
  end
end

例如Processing adminuser:

module Policy::Staff
  class Processing < Base
    def authorized?
      return true if resource.try(:resource_class) == ::Borrow
      return true if resource.try(:resource_class) == ::User && action == :read
      return true if [ 'Reports', 'Categorize' ].include?(resource.try(:name))
      false
    end
  end
end

我总是可以通过在保存时循环遍历 json 来生成策略文件,但该函数看起来很脏。对于特定资源或对其执行的操作,始终采用返回 true 的格式。

在 ActiveAdmin 中执行此类功能的更好方法是什么?

限制: 运行 ActiveAdmin 1.0.0 洗劫 1.8.4

  • 如果我更改/更新这两个中的任何一个,我会得到令人痛苦的错误列表。

【问题讨论】:

    标签: ruby ruby-on-rails-4 activeadmin


    【解决方案1】:

    我推荐 cancan 适配器,它似乎在 ActiveAdmin 1.0.0 中可用。

    首先,通过将cancancancancan 的后续版本)添加到您的 Gemfile 来安装它。然后设置适配器:

    config.authorization_adapter = ActiveAdmin::CanCanAdapter
    

    然后定义一个app/models/ability.rb 类。

    我有这样的东西(借用你的例子并稍微扩展一下):

    class Ability
      include CanCan::Ability
    
      def initialize(user)
        can :read, ActiveAdmin::Page, name: 'Dashboard'
    
        case user.role
        when 'superuser'
          # superusers can do everything, no need to specify
          can :manage, :all
        when 'processing'        
          basic(user)
          processing(user)
        when 'another-role'
          basic(user)
        end
      end
    
    
      private
    
      def basic(user)
        # The user can read all users
        can :read, User
    
        # and they can manage themselves
        can :manage, user
      end
    
      def processing(user)
        can :manage, Borrow
    
        # The conditions hash allows cancan to generate a query
        # to load accessible records as well as check individual
        # records.
        can :manage, OtherThing, name: ['Reports', 'Categorize']
      end
    end
    

    cancancan 的授权相当复杂,但我还没有尝试过其他内置适配器:pundit,所以我不知道它如何比较。

    【讨论】:

      猜你喜欢
      • 2018-07-06
      • 1970-01-01
      • 2020-06-22
      • 2015-09-30
      • 2023-02-04
      • 2022-01-01
      • 2020-04-09
      • 2011-04-25
      相关资源
      最近更新 更多