[ZF-10089] Zend_Log
[zend.git] / documentation / manual / ru / module_specs / Zend_Acl.xml
blob5bdfabb4edd9f8b7acab835f4c53d644d220d956
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.acl.introduction">
4     <title>Введение</title>
6     <para>
7         <classname>Zend_Acl</classname> предоставляет легковесную и гибкую реализацию списка прав
8         доступа (<acronym>ACL</acronym>) и управления привилегиями. Приложение может использовать
9         такие списки для контроля доступа одних объектов к другим - защищенным.
10     </para>
12     <para>
13         В рамках данной документации,
14         <itemizedlist>
15             <listitem>
16                 <para>
17                     <emphasis>Ресурс</emphasis> - объект, доступ к
18                     которому контролируется.
19                 </para>
20             </listitem>
21             <listitem>
22                 <para>
23                     <emphasis>Роль</emphasis> - объект, который
24                     может запрашивать доступ к ресурсу.
25                 </para>
26             </listitem>
27         </itemizedlist>
29         Говоря проще, <emphasis>роли запрашивают доступ к
30         ресурсам</emphasis>.
31         Например, если парковщик запрашивает доступ к автомобилю, то
32         парковщик - это роль, а автомобиль - ресурс, поскольку доступ к
33         автомобилю не может предоставляться всем без исключения.
34     </para>
36     <para>
37         Благодаря спецификации и использованию списка прав доступа (ACL)
38         приложение может контролировать предоставление ролям доступа к ресурсам.
39     </para>
41     <sect2 id="zend.acl.introduction.resources">
42         <title>Ресурсы</title>
43         <para>
44             Создать ресурс в <classname>Zend_Acl</classname> очень просто. <classname>Zend_Acl</classname> предоставляет
45             интерфейс ресурса <classname>Zend_Acl_Resource_Interface</classname> для
46             облегчения процесса создания ресурса. Этот интерфейс содержит только
47             один метод, <code>getResourceId()</code>. Классу достаточно
48             реализовывать этот интерфейс для того, чтобы <classname>Zend_Acl</classname> рассматривал
49             объект этого класса как ресурс. Кроме того, <classname>Zend_Acl</classname>
50             предоставляет <code>Zend_Acl_Resource</code> в качестве базового
51             класса, который разработчики могут расширять по желанию.
52         </para>
53         <para>
54             <classname>Zend_Acl</classname> предоставляет древовидную структуру, в которую могут
55             добавляться различные ресурсы. В этой структуре они могут быть
56             организованы от общих (корень дерева) к специфическим
57             (листья дерева). При запросах к определенным ресурсам в иерархии
58             будет выполнен автоматический поиск правил, относящихся
59             к ресурсам-предкам, учитывающий простое наследование правил.
60             Например, если некое общее
61             правило должно действовать в каждом здании города, то проще
62             прикрепить его к городу, чем крепить к каждому зданию в городе.
63             Однако, для некоторых зданий могут потребоваться исключения из этого
64             правила, в <classname>Zend_Acl</classname> это достигается путем закрепления исключений за
65             каждым зданием, требующим исключений из правила.
66             Ресурс может наследовать только от одного родительского ресурса,
67             однако сам родительский ресурс может,
68             в свою очередь, наследовать от другого родительского ресурса и т.д.
69         </para>
70         <para>
71             <classname>Zend_Acl</classname> также поддерживает права доступа к ресурсам (например,
72             "создание", "чтение", "обновление", "удаление"),
73             разработчик может присваивать правила, которые будут влиять на все
74             или определенные права доступа к ресурсу.
75         </para>
76     </sect2>
78     <sect2 id="zend.acl.introduction.roles">
79         <title>Роли</title>
80         <para>
81             Как и в случае с ресурсами, создавать роль тоже очень просто.
82             Все роли должны реализовывать интерфейс
83             <classname>Zend_Acl_Role_Interface</classname>. Этот интерфейс содержит
84             единственный метод <code>getRoleId()</code>. Кроме того, <classname>Zend_Acl</classname>
85             предоставляет <classname>Zend_Acl_Role</classname> в качестве базового класса,
86             который разработчики могут расширять по желанию.
87         </para>
88         <para>
89             В <classname>Zend_Acl</classname> роль может наследовать от одной или от нескольких
90             ролей. Это реализовано для поддержки
91             наследования правил между ролями. Например, пользовательская роль,
92             такая как "Салли", может принадлежать одной или нескольким
93             родительским ролям, таким как "редактор" и "администратор".
94             Разработчик может привязывать правила к "редактору" и
95             "администратору" раздельно, и "Салли" будет наследовать правила
96             обоих ролей. Нет необходимости привязывать правила непосредственно
97             к "Салли".
98         </para>
99         <para>
100             Хотя множественное наследование ролей - очень полезная возможность,
101             она также усложняет разработку. Следующий пример демонстрирует
102             неопределенное условие и показывает, как <classname>Zend_Acl</classname> решает эту
103             проблему.
104         </para>
105         <example id="zend.acl.introduction.roles.example.multiple_inheritance">
106             <title>Множественное наследование ролей</title>
107             <para>
108                 Следующий код определяет три базовые роли:
109                 "<code>guest</code>", "<code>member</code>" и
110                 "<code>admin</code>", от которых будут наследовать другие роли.
111                 Далее создается "<code>someUser</code>", он наследует от этих
112                 только что созданных трех ролей. Порядок, в котором эти роли
113                 появляются в массиве <varname>$parents</varname>,
114                 важен. При необходимости <classname>Zend_Acl</classname> ищет правила доступа не
115                 только для запрашиваемых ролей (в нашем случае,
116                 "<code>someUser</code>"), но и для ролей, от которых
117                 запрашиваемая роль унаследована
118                 (в нашем примере, "<code>guest</code>", "<code>member</code>" и
119                 "<code>admin</code>"):
120             </para>
121             <programlisting language="php"><![CDATA[
122 $acl = new Zend_Acl();
124 $acl->addRole(new Zend_Acl_Role('guest'))
125     ->addRole(new Zend_Acl_Role('member'))
126     ->addRole(new Zend_Acl_Role('admin'));
128 $parents = array('guest', 'member', 'admin');
129 $acl->addRole(new Zend_Acl_Role('someUser'), $parents);
131 $acl->add(new Zend_Acl_Resource('someResource'));
133 $acl->deny('guest', 'someResource');
134 $acl->allow('member', 'someResource');
136 echo $acl->isAllowed('someUser', 'someResource') ? 'разрешен' : 'запрещен';
137 ]]></programlisting>
138             <para>
139                 Поскольку нет правил, определенных специально для роли
140                 "<code>someUser</code>" и ресурса
141                 "<code>someResource</code>", то <classname>Zend_Acl</classname> должен производить
142                 поиск правил, которые могут быть определены для ролей,
143                 от которых "<code>someUser</code>" наследуется. Сперва
144                 проверяется роль "<code>admin</code>", и обнаруживается, что
145                 для нее не определены правила доступа. Затем проверяется роль
146                 "<code>member</code>", и <classname>Zend_Acl</classname> обнаруживает, что есть правило
147                 разрешающее доступ для "<code>member</code>" к
148                 "<code>someResource</code>".
149             </para>
150             <para>
151                 Если бы <classname>Zend_Acl</classname> продолжил поиск правил, определенных для
152                 родительских ролей, то обнаружил бы, что для
153                 "<code>guest</code>" запрещен доступ к
154                 "<code>someResource</code>". Это пример показывает противоречие,
155                 так как теперь для "<code>someUser</code>" доступ к
156                 "<code>someResource</code>" разрешен и запрещен одновременно.
157                 Конфликт произошел по причине наследования от нескольких ролей.
158             </para>
159             <para>
160                 <classname>Zend_Acl</classname> решает эту неоднозначность, завершая запрос, как только
161                 находит первое правило, которое может быть применено к запросу.
162                 В этом случае, если роль "<code>member</code>"
163                 проверяется раньше, чем роль "<code>guest</code>", то
164                 данный пример выведет "<code>разрешен</code>".
165             </para>
166         </example>
167         <note>
168             <para>
169                 При определении нескольких родительских ролей, не
170                 забывайте, что последний указанный родитель
171                 будет первым в списке поиска правил для запроса авторизации.
172             </para>
173         </note>
174     </sect2>
176     <sect2 id="zend.acl.introduction.creating">
177         <title>Создание списка контроля доступа (ACL)</title>
179         <para>
180             Список контроля доступа (<acronym>ACL</acronym>) может представлять собой любое
181             множество физических или виртуальных объектов. В целях
182             демонстрации, мы создадим базовый
183             функционал <acronym>ACL</acronym> для системы управления содержимым (<acronym>CMS</acronym>),
184             который будет поддерживать нескольких уровней групп к множеству
185             областей. Чтобы создать новый объект <acronym>ACL</acronym>, производим инстанцирование
186             без параметров:
187         </para>
189         <programlisting language="php"><![CDATA[
190 $acl = new Zend_Acl();
191 ]]></programlisting>
193         <note>
194             <para>
195                 До тех пор, пока разработчик не определит какое-либо правило,
196                 разрешающее доступ, <classname>Zend_Acl</classname> отказывает всем ролям в доступе ко
197                 всем привилегиям на все ресурсы.
198             </para>
199         </note>
200     </sect2>
202     <sect2 id="zend.acl.introduction.role_registry">
203         <title>Регистрация ролей</title>
205         <para>
206             <acronym>CMS</acronym> почти всегда нуждаются в иерархии
207             доступа для определения авторских возможностей своих пользователей.
208             Это может быть группа "Гость",
209             предоставляющая ограниченный доступ для демонстрации, группа
210             "Сотрудник" - группа большинства пользователей <acronym>CMS</acronym>,
211             которые производят каждодневные операции, группа "Редактор" - для
212             тех кто публикует и редактирует, архивирует и удаляет контент, и,
213             наконец, группа "Администратор", участники которой могут выполнять
214             все операции, которые доступны участникам других групп, а также
215             управлять закрытой информацией, пользователями,
216             конфигурацией адинистративной части, делать резервное
217             копирование данных и их экспорт.
218             Этот набор прав доступа может быть представлен в реестре ролей,
219             позволяя каждой группе наследовать привилегии
220             родительской группы, при этом имея индивидуальные права доступа.
221             Права доступа могут быть изображены в следующем виде:
222         </para>
224         <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
225           <title>Контроль за доступом для демонстрационной CMS</title>
226           <tgroup cols="3">
227             <thead>
228               <row>
229                 <entry>Название</entry>
230                 <entry>Индивидуальные права</entry>
231                 <entry>Права, унаследованные от</entry>
232               </row>
233             </thead>
234             <tbody>
235               <row>
236                 <entry>Гость (guest)</entry>
237                 <entry>Просмотр (view)</entry>
238                 <entry>Не определено</entry>
239               </row>
240               <row>
241                 <entry>Сотрудник (staff)</entry>
242                 <entry>Редактирование (edit), предложение на публикацию (submit), исправление (revise)</entry>
243                 <entry>Гость</entry>
244               </row>
245               <row>
246                 <entry>Редактор (editor)</entry>
247                 <entry>Публикация (publish), архивирование (archive), удаление (delete)</entry>
248                 <entry>Сотрудник</entry>
249               </row>
250               <row>
251                 <entry>Администратор (administrator)</entry>
252                 <entry>(Обладает всеми правами)</entry>
253                 <entry>Не определено</entry>
254               </row>
255             </tbody>
256           </tgroup>
257         </table>
259         <para>
260             Для этого примера мы используем <classname>Zend_Acl_Role</classname>, но можно
261             было бы использовать любой другой класс,
262             реализующий интерфейс <classname>Zend_Acl_Role_Interface</classname>.
263             Эти группы могут быть добавлены в реестр ролей
264             следующим образом:
265         </para>
267         <programlisting language="php"><![CDATA[
268 $acl = new Zend_Acl();
270 // Добавление групп в реестр ролей с использованием Zend_Acl_Role
271 // Гость не наследует управление доступом
272 $roleGuest = new Zend_Acl_Role('guest');
273 $acl->addRole($roleGuest);
275 // Сотрудник наследует от гостя
276 $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
279 Делает то же самое, что и
280 $acl->addRole(new Zend_Acl_Role('staff'), 'guest');
283 // Редактор наследует от сотрудника
284 $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
286 // Администатор не наследует управление доступом
287 $acl->addRole(new Zend_Acl_Role('administrator'));
288 ]]></programlisting>
290     </sect2>
292     <sect2 id="zend.acl.introduction.defining">
293         <title>Определение контроля доступа</title>
295         <para>
296             Теперь, когда <acronym>ACL</acronym> содержит все необходимые роли, можно определить
297             правила, по которым роли будут иметь доступ к ресурсам. Вы, должно
298             быть, заметили, что мы не определили ни одного отдельного ресурса
299             для этого примера, это упрощает демонстрацию того, что правила
300             применяются ко всем ресурсам. <classname>Zend_Acl</classname> предоставляет реализацию,
301             посредством которой правила должны передаваться
302             от общих к специфическим, минимизируя таким образом количество
303             необходимых правил, так как
304             ресурсы и роли наследуют правила, которые определены для их предков.
305         </para>
307         <para>
308             В результате мы можем определить умеренно сложный набор правил
309             минимальным кодом. Чтобы определить базовые права доступа, описанные
310             выше:
311         </para>
313         <programlisting language="php"><![CDATA[<?php
314 require_once 'Zend/Acl.php';
316 $acl = new Zend_Acl();
318 require_once 'Zend/Acl/Role.php';
320 $roleGuest = new Zend_Acl_Role('guest');
321 $acl->addRole($roleGuest);
322 $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
323 $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
324 $acl->addRole(new Zend_Acl_Role('administrator'));
326 // Гость может только просматривать контент
327 $acl->allow($roleGuest, null, 'view');
329 /* другим способом, предыдущий блок кода может быть записан в таком виде:
330 $acl->allow('guest', null, 'view');
331 //*/
333 // Сотрудник наследует привилегии просмотра у Гостя, но также нуждается в дополнительных привилегиях
334 $acl->allow('staff', null, array('edit', 'submit', 'revise'));
336 // Редактор наследует привилегии просмотра, редактирования, отправки и исправлений у Посетителя
337 // но также нуждается в дополнительных привилегиях
338 $acl->allow('editor', null, array('publish', 'archive', 'delete'));
340 // Администратор не наследует ничего, но обладает всеми привилегиями
341 $acl->allow('administrator');]]></programlisting>
343         <para>
344             Значение <constant>NULL</constant> в вызовах
345             <code>allow()</code> в этом примере используется для
346             указания того, что правила, предоставляющие доступ,
347             действительны для всех ресурсов.
348         </para>
350     </sect2>
352     <sect2 id="zend.acl.introduction.querying">
353         <title>Запросы к ACL</title>
355         <para>
356             Теперь у нас есть гибкий <acronym>ACL</acronym>, который может использоваться для
357             определения того, достаточно ли прав имеет запрашивающий, чтобы
358             производить действия в веб-приложении. Используя метод
359             <code>isAllowed()</code>, производить запросы довольно просто:
360         </para>
362         <programlisting language="php"><![CDATA[
363 echo $acl->isAllowed('guest', null, 'view') ?
364      "разрешен" : "запрещен";
365 // разрешен
367 echo $acl->isAllowed('staff', null, 'publish') ?
368      "разрешен" : "запрещен";
369 // запрещен
371 echo $acl->isAllowed('staff', null, 'revise') ?
372      "разрешен" : "запрещен";
373 // разрешен
375 echo $acl->isAllowed('editor', null, 'view') ?
376      "разрешен" : "запрещен";
377 // разрешен потому, что редактор наследует от гостя
379 echo $acl->isAllowed('editor', null, 'update') ?
380      "разрешен" : "запрещен";
381 // запрещен потому, что нет правила, разрешающего обновление (update)
383 echo $acl->isAllowed('administrator', null, 'view') ?
384      "разрешен" : "запрещен";
385 // разрешен потому, что администратор обладает всеми привилегиями
387 echo $acl->isAllowed('administrator') ?
388      "разрешен" : "запрещен";
389 // разрешен потому, что администратор обладает всеми привилегиями
391 echo $acl->isAllowed('administrator', null, 'update') ?
392      "разрешен" : "запрещен";
393 // разрешен потому, что администратор обладает всеми привилегиями
394 ]]></programlisting>
396     </sect2>
397 </sect1>
398 <!--
399 vim:se ts=4 sw=4 et: