Changed ACL documentation
This commit is contained in:
parent
2437f72f08
commit
517a0e6df1
|
@ -5,7 +5,14 @@
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
ACL предназначена для контроля прав пользователя на выполнение действий в
|
ACL предназначена для контроля прав пользователя на выполнение действий в
|
||||||
системе доступа к моделям по областям видимости.
|
системе и доступа к моделям по областям видимости.
|
||||||
|
|
||||||
|
Решаемые задачи
|
||||||
|
---------------
|
||||||
|
|
||||||
|
* Проверка наличия у пользователя прав для выполнения метода контроллера;
|
||||||
|
* Прозрачная фильтрация моделей для исключения невидимых для пользователя
|
||||||
|
записей.
|
||||||
|
|
||||||
Возможности
|
Возможности
|
||||||
-----------
|
-----------
|
||||||
|
@ -20,15 +27,55 @@ ACL предназначена для контроля прав пользова
|
||||||
* Объединение прав `acter`-ов на глубину одной модели (см. далее);
|
* Объединение прав `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`;
|
* Добавить к таблице моделей поле `visibility:text`;
|
||||||
* Добавить `attr_accessible :visibility` в модель;
|
* Добавить `attr_accessible :visibility` в модель;
|
||||||
* Создать `scope :by_visibility`, принимающий аргументом массив областей
|
* Создать `scope :by_visibility`, принимающий аргументом массив областей
|
||||||
видимости;
|
видимости.
|
||||||
|
|
||||||
После выполнения этих действий на странице редактирования роли появится поле
|
После выполнения этих действий на странице редактирования роли появится поле
|
||||||
выбора областей видимости для этой модели.
|
выбора областей видимости для этой модели.
|
||||||
|
|
||||||
Пример:
|
### Пример:
|
||||||
|
|
||||||
model VisibilitiesExample < ActiveRecord::Base
|
model VisibilitiesExample < ActiveRecord::Base
|
||||||
VISIBILITIES = ['open', 'hidden', 'open_for_admins']
|
VISIBILITIES = ['open', 'hidden', 'open_for_admins']
|
||||||
|
@ -64,6 +111,8 @@ ACL предназначена для контроля прав пользова
|
||||||
scope :by_visibility, lambda {|v| {:conditions => ['visibility in (?)', v]}}
|
scope :by_visibility, lambda {|v| {:conditions => ['visibility in (?)', v]}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
*Назначение методов описано в API*
|
||||||
|
|
||||||
Задание типа модели
|
Задание типа модели
|
||||||
-------------------
|
-------------------
|
||||||
*Этот функционал скорее всего будет изменяться*
|
*Этот функционал скорее всего будет изменяться*
|
||||||
|
@ -82,7 +131,7 @@ ACL предназначена для контроля прав пользова
|
||||||
которой аргументом присвоить имя/имена связей с моделями, из которых должны
|
которой аргументом присвоить имя/имена связей с моделями, из которых должны
|
||||||
браться роли.
|
браться роли.
|
||||||
|
|
||||||
Примеры:
|
### Примеры:
|
||||||
|
|
||||||
* Модель, являющаяся __acter__:
|
* Модель, являющаяся __acter__:
|
||||||
|
|
||||||
|
@ -121,6 +170,78 @@ ACL предназначена для контроля прав пользова
|
||||||
has_many :objects, :as => :target, :class_name => 'Relation'
|
has_many :objects, :as => :target, :class_name => 'Relation'
|
||||||
end
|
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
|
API для работы с ACL
|
||||||
--------------------
|
--------------------
|
||||||
*Этот функционал скорее всего будет изменяться*
|
*Этот функционал скорее всего будет изменяться*
|
||||||
|
@ -130,23 +251,38 @@ API для работы с ACL
|
||||||
* Методы классов:
|
* Методы классов:
|
||||||
- `relationable` -- устанавливает, кем является модель (acter/target)
|
- `relationable` -- устанавливает, кем является модель (acter/target)
|
||||||
- `relationable?` -- может ли иметь связь с ролью/ролями с другими
|
- `relationable?` -- может ли иметь связь с ролью/ролями с другими
|
||||||
- `relation_acters` -- список моделей, которые могут иметь роли по отношению к другим (след. метод)
|
- `relation_acters` -- список моделей, которые могут иметь роли
|
||||||
- `relation_targets` -- список моделей, над которыми могут совершаться действия
|
по отношению к другим (след. метод)
|
||||||
- `relation_acter? (model)`, `relation_target? (model)` -- является ли тем или другим
|
- `relation_targets` -- список моделей, над которыми могут совершаться
|
||||||
- `inherit_rights_from (:relation_name | [:relation_names])` -- права из каких связанных моделей наследовать
|
действия
|
||||||
- `visible_to (model)` -- все видимые для модели записи, может включаться в цепочку (например, для paginate)
|
- `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_to(acter, role)` -- привязать acter-а с ролью к текущей записи
|
||||||
- `add_role_on(target, role)` -- привязать текущую модель с ролью
|
- `add_role_on(target, role)` -- привязать текущую модель с ролью
|
||||||
- `roles_to(object)` -- если object == :system, возвращает глобальные роли текущей записи, если передана запись -- то роли текущей модели над записью
|
- `roles_to(object)` -- если object == :system, возвращает глобальные роли
|
||||||
- `rights_to(object)` -- аргументы те же, но возвращается список прав, собранный из всех ролей
|
текущей записи, если передана запись -- то роли текущей модели над записью
|
||||||
- `right_to(controller_name, action)` -- возвращает запись с правом на выполнение действия action в контроллере c именем controller_name
|
- `rights_to(object)` -- аргументы те же, но возвращается список прав,
|
||||||
- `can_perform? (controller_name, action, target = :system)` -- показывает, может ли текущая модель выполнить действие контроллера над целью
|
собранный из всех ролей
|
||||||
|
- `right_to(controller_name, action)` -- возвращает запись с правом на
|
||||||
|
выполнение действия action в контроллере c именем `controller_name`
|
||||||
|
- `can_perform? (controller_name, action, target = :system)` -- показывает,
|
||||||
|
может ли текущая модель выполнить действие контроллера над целью
|
||||||
|
|
||||||
### Методы потомков `ActiveController::Base`
|
### Методы потомков `ActiveController::Base`
|
||||||
- `can_perform? (target = :system)` -- может ли current_user выполнить текущее действие
|
*Возможно, будут вынесены в хелпер для универсализации системы*
|
||||||
- `check_global_rights` -- делает редирект назад, если пользователь вообще не может совершить текущее действие
|
|
||||||
- `roles_to(object)` -- возвращает список ролей current_user-а по отношению к объекту
|
- `can_perform? (target = :system)` -- может ли `current_user` выполнить
|
||||||
- `rights_to(object)` -- возвращает список прав current_user-а по отношению к объекту
|
текущее действие
|
||||||
|
- `check_global_rights` -- делает редирект назад, если пользователь вообще
|
||||||
|
не может совершить текущее действие
|
||||||
|
- `roles_to(object)` -- возвращает список ролей `current_user`-а по отношению
|
||||||
|
к объекту
|
||||||
|
- `rights_to(object)` -- возвращает список прав `current_user`-а по отношению
|
||||||
|
к объекту
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue