Changed ACL documentation
This commit is contained in:
parent
2437f72f08
commit
517a0e6df1
|
@ -5,7 +5,14 @@
|
|||
--------------
|
||||
|
||||
ACL предназначена для контроля прав пользователя на выполнение действий в
|
||||
системе доступа к моделям по областям видимости.
|
||||
системе и доступа к моделям по областям видимости.
|
||||
|
||||
Решаемые задачи
|
||||
---------------
|
||||
|
||||
* Проверка наличия у пользователя прав для выполнения метода контроллера;
|
||||
* Прозрачная фильтрация моделей для исключения невидимых для пользователя
|
||||
записей.
|
||||
|
||||
Возможности
|
||||
-----------
|
||||
|
@ -20,15 +27,55 @@ ACL предназначена для контроля прав пользова
|
|||
* Объединение прав `acter`-ов на глубину одной модели (см. далее);
|
||||
* Разграничение назначения ролей по классам (не завершено, на данный
|
||||
момент не критично);
|
||||
* Разграничение ролей на глобальные и локальные (см. далее);
|
||||
* Разграничение ролей на глобальные и локальные (см. далее).
|
||||
|
||||
Типы моделей
|
||||
------------
|
||||
Типы моделей, с которыми взаимодействует ACL
|
||||
--------------------------------------------
|
||||
|
||||
* __ActerModel__ -- модель, которая может выполнять действия, разрешенные
|
||||
ролями, над другими моделями;
|
||||
* __TargetTarget__ -- модель, над которой могут выполняться действия,
|
||||
разрешенные ролями.
|
||||
|
||||
__ActerModel__ может иметь глобальную роль, которая определяет возможность
|
||||
выполнения действий без привязки к конкретному экземпляру __TargetModel__ и
|
||||
неограниченное количество прав по отношению к конкретному экземпляру
|
||||
__TargetModel__.
|
||||
|
||||
__TODO__: *Реализовать дополнение необходимым функционалом моделей, выбранных
|
||||
в качестве __ActerModel__ или __TargetModel__ при декларировании их роли в
|
||||
системе*
|
||||
|
||||
Схема взаимодействия объектов ACL
|
||||
---------------------------------
|
||||
|
||||
Функционал ACL реализуется путем взаимодействия моделей `Right, Role, Relation`,
|
||||
реализующих основной функционал и особых моделей проекта, обозначенных на схеме
|
||||
как `ActerModel` и `TargetModel`.
|
||||
|
||||
Экземпляры __ActerModel__ и __TargetModel__ связываются посредством модели
|
||||
`Relation`, через которую экземпляр __ActerModel__ получает неограниченное
|
||||
количество ролей по отношению к экземпляру __TargetModel__.
|
||||
|
||||
### Схема связей моделей:
|
||||
|
||||
--------------
|
||||
| ActerModel |
|
||||
/ --------------
|
||||
--------- -------- |
|
||||
| Right | | Role | V
|
||||
--------- -------- ------------
|
||||
... <= ... <= | Relation |
|
||||
--------- -------- ------------
|
||||
| Right | | Role | |
|
||||
--------- -------- V
|
||||
---------------
|
||||
| TargetModel |
|
||||
---------------
|
||||
|
||||
* Обозначения: <= -- Связь с несколькими моделями
|
||||
<-,/,| -- Связь с одной моделью
|
||||
|
||||
* __Acter__ - модель, которая может выполнять действия, разрешенные ролями,
|
||||
над другими моделями;
|
||||
* __Target__ - модель, над которой могут выполняться действия, разрешенные
|
||||
ролями;
|
||||
|
||||
Генератор прав
|
||||
--------------
|
||||
|
@ -50,12 +97,12 @@ ACL предназначена для контроля прав пользова
|
|||
* Добавить к таблице моделей поле `visibility:text`;
|
||||
* Добавить `attr_accessible :visibility` в модель;
|
||||
* Создать `scope :by_visibility`, принимающий аргументом массив областей
|
||||
видимости;
|
||||
видимости.
|
||||
|
||||
После выполнения этих действий на странице редактирования роли появится поле
|
||||
выбора областей видимости для этой модели.
|
||||
|
||||
Пример:
|
||||
### Пример:
|
||||
|
||||
model VisibilitiesExample < ActiveRecord::Base
|
||||
VISIBILITIES = ['open', 'hidden', 'open_for_admins']
|
||||
|
@ -64,6 +111,8 @@ ACL предназначена для контроля прав пользова
|
|||
scope :by_visibility, lambda {|v| {:conditions => ['visibility in (?)', v]}}
|
||||
end
|
||||
|
||||
*Назначение методов описано в API*
|
||||
|
||||
Задание типа модели
|
||||
-------------------
|
||||
*Этот функционал скорее всего будет изменяться*
|
||||
|
@ -82,7 +131,7 @@ ACL предназначена для контроля прав пользова
|
|||
которой аргументом присвоить имя/имена связей с моделями, из которых должны
|
||||
браться роли.
|
||||
|
||||
Примеры:
|
||||
### Примеры:
|
||||
|
||||
* Модель, являющаяся __acter__:
|
||||
|
||||
|
@ -121,6 +170,78 @@ ACL предназначена для контроля прав пользова
|
|||
has_many :objects, :as => :target, :class_name => 'Relation'
|
||||
end
|
||||
|
||||
*Назначение методов описано в API*
|
||||
|
||||
Использование ACL в контроллере
|
||||
-------------------------------
|
||||
|
||||
Если необходимо ограничить доступ ко всем методам контроллера по глобальной
|
||||
роли пользователя вне зависимости от текущей модели, необходимо установить
|
||||
`before_filter :check_global_rights`.
|
||||
В случае, если у пользователя нет прав для выполнения текущего действия, он
|
||||
будет переотправлен на предыдущую страницу.
|
||||
|
||||
Если необходимо проверить, может ли пользователь выполнить конкретное действие,
|
||||
необходимо в начале этого метода вызвать метод `can_perform?`. Если методу
|
||||
передан параметр, являющийся экземпляром класса __TargetModel__, метод возвратит
|
||||
`true`, если одна или несколько ролей пользователя над этой моделью позволяет
|
||||
ему выполнить может выполнить действие и `false` в противном случае. Если
|
||||
необязательный параметр опущен, или в качестве параметра передано `:system`,
|
||||
учитываются только глобальные роли.
|
||||
|
||||
### Примеры
|
||||
|
||||
* Контроллер, некоторые методы которого доступны для всех:
|
||||
|
||||
class StuffController < ApplicationController
|
||||
def index # доступ у всех
|
||||
...
|
||||
end
|
||||
|
||||
def show # 'Что-то полезное' выполнится только у тех, чьи роли над
|
||||
# @data позволяют выполнить конкретное действие.
|
||||
@data = Stuff.find(params[:id])
|
||||
if can_perform? @data
|
||||
#что-то полезное
|
||||
else
|
||||
# сообщаем пользователю, что он не может выполнить действие
|
||||
end
|
||||
end
|
||||
|
||||
def create # 'Что-то полезное' выполнится только у тех, чьи
|
||||
# глобальные роли позволяют выполнить метод
|
||||
if can_perform?
|
||||
# что-то полезное
|
||||
else
|
||||
# сообщаем пользователю, что он не может выполнить действие
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
* Контроллер, доступ к методам которого возможен только при наличии необходимых
|
||||
прав в глобальных ролях:
|
||||
|
||||
class StuffController < ApplicationController
|
||||
before_filter :check_global_rights # разрешаем доступ только тем,
|
||||
# чьи роли это позволяют.
|
||||
|
||||
def index # доступ только у тех, кому это позволяет глобальная роль
|
||||
...
|
||||
end
|
||||
|
||||
def show # 'Что-то полезное' выполнится только у тех, чьи роли
|
||||
# над @data это позволяют
|
||||
@data = Stuff.find(params[:id])
|
||||
if can_perform? @data
|
||||
#что-то полезное
|
||||
else
|
||||
# сообщаем пользователю, что он не может выполнить действие
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
API для работы с ACL
|
||||
--------------------
|
||||
*Этот функционал скорее всего будет изменяться*
|
||||
|
@ -130,23 +251,38 @@ API для работы с ACL
|
|||
* Методы классов:
|
||||
- `relationable` -- устанавливает, кем является модель (acter/target)
|
||||
- `relationable?` -- может ли иметь связь с ролью/ролями с другими
|
||||
- `relation_acters` -- список моделей, которые могут иметь роли по отношению к другим (след. метод)
|
||||
- `relation_targets` -- список моделей, над которыми могут совершаться действия
|
||||
- `relation_acter? (model)`, `relation_target? (model)` -- является ли тем или другим
|
||||
- `inherit_rights_from (:relation_name | [:relation_names])` -- права из каких связанных моделей наследовать
|
||||
- `visible_to (model)` -- все видимые для модели записи, может включаться в цепочку (например, для paginate)
|
||||
- `relation_acters` -- список моделей, которые могут иметь роли
|
||||
по отношению к другим (след. метод)
|
||||
- `relation_targets` -- список моделей, над которыми могут совершаться
|
||||
действия
|
||||
- `relation_acter? (model)`, `relation_target? (model)` -- является ли
|
||||
тем или другим
|
||||
- `inherit_rights_from (:relation_name | [:relation_names])` -- права из
|
||||
каких связанных моделей наследовать
|
||||
- `visible_to (model)` -- все видимые для модели записи, может
|
||||
включаться в цепочку (например, для paginate)
|
||||
|
||||
* Методы инстансов:
|
||||
- `add_role_to(acter, role)` -- привязать acter-а с ролью к текущей записи
|
||||
- `add_role_on(target, role)` -- привязать текущую модель с ролью
|
||||
- `roles_to(object)` -- если object == :system, возвращает глобальные роли текущей записи, если передана запись -- то роли текущей модели над записью
|
||||
- `rights_to(object)` -- аргументы те же, но возвращается список прав, собранный из всех ролей
|
||||
- `right_to(controller_name, action)` -- возвращает запись с правом на выполнение действия action в контроллере c именем controller_name
|
||||
- `can_perform? (controller_name, action, target = :system)` -- показывает, может ли текущая модель выполнить действие контроллера над целью
|
||||
- `roles_to(object)` -- если object == :system, возвращает глобальные роли
|
||||
текущей записи, если передана запись -- то роли текущей модели над записью
|
||||
- `rights_to(object)` -- аргументы те же, но возвращается список прав,
|
||||
собранный из всех ролей
|
||||
- `right_to(controller_name, action)` -- возвращает запись с правом на
|
||||
выполнение действия action в контроллере c именем `controller_name`
|
||||
- `can_perform? (controller_name, action, target = :system)` -- показывает,
|
||||
может ли текущая модель выполнить действие контроллера над целью
|
||||
|
||||
### Методы потомков `ActiveController::Base`
|
||||
- `can_perform? (target = :system)` -- может ли current_user выполнить текущее действие
|
||||
- `check_global_rights` -- делает редирект назад, если пользователь вообще не может совершить текущее действие
|
||||
- `roles_to(object)` -- возвращает список ролей current_user-а по отношению к объекту
|
||||
- `rights_to(object)` -- возвращает список прав current_user-а по отношению к объекту
|
||||
*Возможно, будут вынесены в хелпер для универсализации системы*
|
||||
|
||||
- `can_perform? (target = :system)` -- может ли `current_user` выполнить
|
||||
текущее действие
|
||||
- `check_global_rights` -- делает редирект назад, если пользователь вообще
|
||||
не может совершить текущее действие
|
||||
- `roles_to(object)` -- возвращает список ролей `current_user`-а по отношению
|
||||
к объекту
|
||||
- `rights_to(object)` -- возвращает список прав `current_user`-а по отношению
|
||||
к объекту
|
||||
|
||||
|
|
Loading…
Reference in New Issue