Каков наилучший подход для применения авторизации доступа на основе ролей в Active Admin? - PullRequest
0 голосов
/ 16 ноября 2018

Если я использую только 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 Администратор:

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

  • Если я изменяю / обновляю любую из двух, я получаю болезненный список ошибок.

1 Ответ

0 голосов
/ 14 декабря 2018

Я рекомендую адаптер cancan, который, по-видимому, доступен в ActiveAdmin 1.0.0.

Сначала установите cancancan (преемник cancan), добавив его в свой 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, поэтому я не знаю, как он сравнивается.

...