Система динамических ролей и разрешений в приложении Rails
Мне нужно создать системы разрешений на основе ролей в моем приложении Rails. Я был бы полностью доволен CanCan, но главная проблема - она должна быть динамичной, поэтому администратор должен иметь возможность назначать разрешения и создавать новые роли. Разрешения могут быть простыми ограничениями для контроллера/действия и могут быть связаны с данными, например, некоторые пользователи могут редактировать только свои собственные профили, а некоторые из них могут редактировать профили всех пользователей в конкретной группе. И было бы неплохо позволить администратору создавать новые разрешения.
То, о чем я думаю, это хранить в db контроллер/действие и некоторые ограничения, связанные с данными (я действительно запутался здесь, чтобы определить их). Так что, пожалуйста, дайте мне несколько советов, как лучше всего организовать разрешения?
Любые мысли очень ценятся
Ответы
Ответ 1
Если вам нравится CanCan, я думаю, что лучше всего использовать его. Вот краткое руководство по хранению способностей в базе данных, поэтому не-программисты могут их обновить:
https://github.com/ryanb/cancan/wiki/Abilities-in-Database
Если вы действительно, действительно хотите реализовать такую систему самостоятельно. В зависимости от ваших потребностей я предлагаю вам как можно проще реализовать его.
В случае, если вам нужны только пользователи для доступа к модулям (определенные контроллеры). Вы можете сделать:
1) Хранить все разрешения пользователей точно так же, как сериализованные поля → http://apidock.com/rails/ActiveRecord/Base/serialize/class
class User
serialize :permissions, Array
def access_to?(module)
permissions.include? module.to_s
end
end
Некоторая проверка при установке этого поля будет приятной.
2) Просто сделайте проверку сверху каждого контроллера, если текущий пользователь имеет доступ к этому контроллеру (раздел)
class ApplicationController
private
def self.require_access_to(module)
before_filter do |c|
unless c.send(:current_user).try :access_to?(module)
c.send :render_no_presmissions_page
end
end
endposible
end
class AdminNewsController
require_access_to :news
end
Конечно, это только начальная позиция, откуда вы можете легко развиваться.
Ответ 2
[ РЕДАКТИРОВАТЬ Ссылка, предоставленная @RadoslavStankov, является лучшим ответом.]
Вы можете сделать это с CanCan легко. Просто создайте модель для разрешений (которая has_and_belongs_to_many :users
), а в вашем Ability#initialize
загрузите разрешения, соответствующие пользователю из модели, и скажите, что пользователь can
выполняет их. Затем создайте соответствующий пользовательский интерфейс для администрирования этой модели.
Что-то вроде этого:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
user.permissions.each do |permission|
can permission.symbol, permission.scope
end
user.prohibitions.each do |permission|
cannot permission.symbol, permission.scope
end
end
end
где scope
возвращает что-то вроде :all
для области nil
или Object.const_get(@scope_name)
в противном случае... Играйте с ним. Во всяком случае, это выполнимо.
Более сложные вещи CanCan, вероятно, будут более сложными (duh) - например, условные разрешения - но это тоже будет сука для администрирования, поэтому я думаю, этого должно быть достаточно для большинства приложений.