Использование Declarative_authorization для ограничения результатов в модели - PullRequest
2 голосов
/ 03 мая 2011

Я использую декларативный гем авторизации для разрешений в проекте rails и пытаюсь ограничить вывод из модели на основе разрешений пользователя.

Мой сокращенный файл авторизации выглядит следующим образом:

roles do
  role :supervisor
    has_permission_on :people, :to => :manage_all
  end

  role :basic_user
    has_permission_on :people, :to => :manage_subordinates
  end
end

privileges do
  privilege :manage_subordinates do
    includes :subordinate_records
  end

  privilege :manage_all do
    includes :all_records
  end
end

В моей модели people у меня есть статический метод, который я хочу выглядеть следующим образом

def self.supervised_by(user)
  if user.permitted_to? :all_records
    #return all of the records
  elsif user.permitted_to? :subordinate_records
    #return some of the records
  else
    #return none of the records
  end
end

Похоже, что есть поддержка этого с использованием объекта AuthorizationInModel в документации, использующей with_permissions_to или allow_to.Я не смог выяснить, как использовать эти функции на основе документации или как вернуть список привилегий текущего пользователя для текущей модели.

Есть идеи?

Ответы [ 2 ]

1 голос
/ 06 мая 2011

Я нашел альтернативное решение, используя встроенный метод if-attribute. Изначально я отошел от этого, потому что я использовал модели без пространств имен и контроллеры и представления с пространством имен. Эта структура является артефактом оригинальной версии проекта, над которым я работаю. Большая часть моей работы получала декларативное разрешение для работы с этой структурой.

Основной частью информации, которая мне не была ясна, было то, как назвать разрешения в частично пространственной среде имен. Модель ожидала название модели (: people), контроллер ожидал пространство имен и модель (: staff_people), и представления не заботились, пока вы их выбрали. Решение, которое я выбрал, состояло в том, чтобы использовать имя модели и явно устанавливать контекст в каждом контроллере. Если контекст не установлен в контроллере, использование filter_access_to не работает, потому что он будет искать разрешение staff_people, а не правильное разрешение, people.

В файле конфигурации декларативной авторизации я даю полные разрешения для администрирования и частичные разрешения для супервизора. person.supervised возвращает массив себя и всех других контролируемых людей.

roles do
  role :administrator
    has_permission_on :people, :to => [:create, :read, :update, :delete]
  end

  role :supervisor
    has_permission_on :people do
      to => [:create, :read, :update, :delete]
      if_attribute :id => is_in { Person.find_by_user_id(user.id).supervised }
    end
  end
end

Чтобы получить доступ к этой информации в контроллере пространства имен, я использую filer_resource_access.

module Staff
  class PeopleController < ApplicationController
    filter_resource_access :context => :people

    def index
      @people = People.with_permissions_to(:read)
    end

Я обнаружил, что используя

filter_access_to :all, :with_attribute => true

не работает для методов, которые должны использовать with_permissions_to и разрешение if_attribute. Я не уверен, почему это было проблемой

По-прежнему необходимо использовать filter_access_to для нестандартных действий контроллера, которые не включают в себя идентификатор, извлекающий одну запись как часть аргументов. Например, если действие с именем part_timers возвращает список людей, похоже, что это решение должно работать:

filter_resource_access :context => :people, :additional_member => { :part_timers => :read }

Правильное решение - сохранить filter_resource_access как есть и добавить filter_access_to для этого действия

filter_resource_access :context => :people
fitler_access_to :part_timers, :required => :read, :context => people
0 голосов
/ 04 мая 2011

Может быть лучший способ сделать это, но он должен работать для вашего метода supervised_by, если все остальное настроено правильно.

def self.supervised_by(user)
  if Person.new.permitted_to? :all_records, :user=>user
    #return all of the records
  elsif Person.new.permitted_to? :subordinate_records, :user=>user
    #return some of the records
  else
    #return none of the records
  end
end
...