<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Изучаем Web &#187; acl</title>
	<atom:link href="http://brotkin.ru/tag/acl/feed/" rel="self" type="application/rss+xml" />
	<link>http://brotkin.ru</link>
	<description>ковыряемся в Internet</description>
	<lastBuildDate>Wed, 02 May 2012 12:49:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>A1/A2/Acl &#8211; больше, чем Auth</title>
		<link>http://brotkin.ru/2009/09/01/a1-a2-acl/</link>
		<comments>http://brotkin.ru/2009/09/01/a1-a2-acl/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 06:37:43 +0000</pubDate>
		<dc:creator>biakaveron</dc:creator>
				<category><![CDATA[Kohana3]]></category>
		<category><![CDATA[cправочник]]></category>
		<category><![CDATA[acl]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[modules]]></category>

		<guid isPermaLink="false">http://brotkin.ru/?p=251</guid>
		<description><![CDATA[На электронную почту пришло письмо с просьбой более подробно (и менее сумбурно) описать набор модулей A1/A2/Acl, которые я упоминал ранее. Поскольку Ko3 пока что не предоставляет достаточно поводов для &#8220;блогомарательства&#8221;, предлагаю остановиться на данном замечательном инструменте.
О чем вообще речь?
Модули A1/A2/Acl предназначены для управления правами доступа пользователей. Дистрибутив Kohana v2.3 предоставляет нам только модуль Auth, который [...]]]></description>
			<content:encoded><![CDATA[<p>На электронную почту пришло письмо с просьбой более подробно (и менее сумбурно) описать набор модулей <strong>A1/A2/Acl</strong>, которые я упоминал <a href="http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/">ранее</a>. Поскольку <strong>Ko3</strong> пока что не предоставляет достаточно поводов для &#8220;блогомарательства&#8221;, предлагаю остановиться на данном замечательном инструменте.</p>
<h2>О чем вообще речь?</h2>
<p>Модули <strong>A1/A2/Acl</strong> предназначены для управления правами доступа пользователей. Дистрибутив <strong>Kohana v2.3</strong> предоставляет нам только модуль <strong>Auth</strong>, который <a href="http://brotkin.ru/2009/07/03/razbiraem-modul-auth/">позволит</a> контролировать минимальные доступные действия &#8211; <a href="http://brotkin.ru/2009/01/26/auth_example1/">регистрация</a>, <a href="http://brotkin.ru/2009/01/29/auth_example2/">вход (<em>login</em>) и выход (<em>logout</em>)</a>. Но ведь помимо этого пользователь взаимодействует с различными объектами (ресурсами) сайта, и эти взаимодействия должны быть каким-то образом регламентированы. Самый простой пример &#8211; блог. Гости должны иметь возможность читать записи, авторизованные пользователи также могут комментировать, а администратор (владелец блога) &#8211; создавать записи и редактировать комментарии.</p>
<h2>Подготовка к работе</h2>
<p>Для ветки <strong>2.3.x</strong> модули расположены <a href="http://github.com/Wouterrr/kohanamodules2.3.2/tree/master">здесь</a>. Нас интересуют модули <strong>A1</strong>, <strong>A2</strong> и <strong>Acl</strong>, а также демка с примером возможностей модулей <strong>A2</strong> и <strong>Acl</strong> (она называется <strong>a2-acl-demo</strong>). Просто подкладываем их в папку <em>MODPATH</em> и добавляем в список модулей в <em>config.php</em>. Если запустить метод <strong>db</strong> контроллера <strong>a2demo</strong> (<em>http://localhost/a2demo/db</em>), то мы увидим минимально необходимую схему БД для дальнейшей работы с демо-модулем:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">TABLE</span> <span style="color: #990099; font-weight: bold;">IF <span style="color: #CC0099; font-weight: bold;">NOT</span> EXISTS</span> <span style="color: #008000;">`users`</span> <span style="color: #FF00FF;">&#40;</span>
		  <span style="color: #008000;">`id`</span> <span style="color: #999900; font-weight: bold;">int</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">12</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #FF9900; font-weight: bold;">unsigned</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span> <span style="color: #FF9900; font-weight: bold;">auto_increment</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`username`</span> <span style="color: #999900; font-weight: bold;">varchar</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">32</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span> <span style="color: #990099; font-weight: bold;">default</span> <span style="color: #008000;">''</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`password`</span> <span style="color: #000099;">char</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">50</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`token`</span> <span style="color: #999900; font-weight: bold;">varchar</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">32</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">default</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`logins`</span> <span style="color: #999900; font-weight: bold;">int</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #FF9900; font-weight: bold;">unsigned</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span> <span style="color: #990099; font-weight: bold;">default</span> <span style="color: #008000;">'0'</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`last<span style="color: #008080; font-weight: bold;">_</span>login`</span> <span style="color: #999900; font-weight: bold;">int</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">10</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #FF9900; font-weight: bold;">unsigned</span> <span style="color: #990099; font-weight: bold;">default</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`role`</span> <span style="color: #999900; font-weight: bold;">enum</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">'user'</span><span style="color: #000033;">,</span><span style="color: #008000;">'admin'</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span>
		  <span style="color: #990099; font-weight: bold;">PRIMARY KEY</span>  <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`id`</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span>
		  <span style="color: #FF9900; font-weight: bold;">UNIQUE</span> <span style="color: #990099; font-weight: bold;">KEY</span> <span style="color: #008000;">`uniq<span style="color: #008080; font-weight: bold;">_</span>username`</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`username`</span><span style="color: #FF00FF;">&#41;</span>
		<span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">ENGINE</span><span style="color: #CC0099;">=</span><span style="color: #990099; font-weight: bold;">InnoDB</span>  <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #FF9900; font-weight: bold;">CHARSET</span><span style="color: #CC0099;">=</span>utf8<span style="color: #000033;">;</span>
&nbsp;
		<span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">TABLE</span> <span style="color: #990099; font-weight: bold;">IF <span style="color: #CC0099; font-weight: bold;">NOT</span> EXISTS</span> <span style="color: #008000;">`blogs`</span> <span style="color: #FF00FF;">&#40;</span>
		  <span style="color: #008000;">`id`</span> <span style="color: #999900; font-weight: bold;">int</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">12</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #FF9900; font-weight: bold;">unsigned</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span> <span style="color: #FF9900; font-weight: bold;">auto_increment</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`user<span style="color: #008080; font-weight: bold;">_</span>id`</span> <span style="color: #999900; font-weight: bold;">int</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">12</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #FF9900; font-weight: bold;">unsigned</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span>
		  <span style="color: #008000;">`text`</span> <span style="color: #999900; font-weight: bold;">text</span> <span style="color: #CC0099; font-weight: bold;">NOT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span><span style="color: #000033;">,</span>
		  <span style="color: #990099; font-weight: bold;">PRIMARY KEY</span>  <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`id`</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">,</span>
		  <span style="color: #990099; font-weight: bold;">KEY</span> <span style="color: #008000;">`user<span style="color: #008080; font-weight: bold;">_</span>id`</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">`user<span style="color: #008080; font-weight: bold;">_</span>id`</span><span style="color: #FF00FF;">&#41;</span>
		<span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">ENGINE</span><span style="color: #CC0099;">=</span><span style="color: #990099; font-weight: bold;">InnoDB</span>  <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #FF9900; font-weight: bold;">CHARSET</span><span style="color: #CC0099;">=</span>utf8<span style="color: #000033;">;</span></pre></div></div>

<p></code></p>
<p>Т.е. необходимо создать таблицу для пользователей (она несильно отличается от используемой в <strong>Auth</strong>) и таблицу для сохранения наших разделяемых ресурсов (т.е. записей блога). Естественно, для настоящего блога эта табличка уж очень неактуальна, но сейчас цель &#8211; показать принцип работы модулей. Сами таблицы можно не заполнять &#8211; демо-контроллер позволит нам зарегистрироваться и немного поработать над блогом.</p>
<h2>Знакомство с демо-версией</h2>
<p>Откроем <em>http://localhost/a2demo/</em>. Поскольку мы не представились системе, нам предлагают войти или зарегистрироваться.<br />
<div id="attachment_252" class="wp-caption aligncenter" style="width: 291px"><a href="http://brotkin.ru/wp-content/uploads/login.jpg"><img src="http://brotkin.ru/wp-content/uploads/login.jpg" alt="Блок авторизации для гостя" title="Блок авторизации для гостя" width="281" height="38" class="size-full wp-image-252" /></a><p class="wp-caption-text">Блок авторизации для гостя</p></div><br />
Выберем второй вариант и получим следующую форму<br />
<div id="attachment_253" class="wp-caption aligncenter" style="width: 363px"><a href="http://brotkin.ru/wp-content/uploads/register1.jpg"><img src="http://brotkin.ru/wp-content/uploads/register1.jpg" alt="Форма для регистрации" title="Форма для регистрации" width="353" height="107" class="size-full wp-image-253" /></a><p class="wp-caption-text">Форма для регистрации</p></div><br />
Как мы видим, необходимо ввести логин, пароль (дважды) и указать роль. Доступна роль обычного пользователя (<em>user</em>) и администратора (<em>admin</em>). Ниже выведена информация о содержимом массива <strong>$_POST</strong> и переменной <strong>$user</strong>, в которой будет сохранен пользователь. Не обращайте на нее внимания <img src='http://brotkin.ru/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
После успешной регистрации мы автоматически авторизовываемся и отправляемся на главную страницу демки. Теперь мы можем собственно управлять ресурсами. Вот так выглядит страница глазами обычного пользователя (я уже создал несколько записей в блоге):<br />
<div id="attachment_255" class="wp-caption aligncenter" style="width: 395px"><a href="http://brotkin.ru/wp-content/uploads/user_actions1.jpg"><img src="http://brotkin.ru/wp-content/uploads/user_actions1.jpg" alt="Что видит пользователь" title="Что видит пользователь" width="385" height="240" class="size-full wp-image-255" /></a><p class="wp-caption-text">Что видит пользователь</p></div><br />
Помимо собственно добавления записей предлагается изменить или удалить существующие. Конечно, только администратор имеет возможность управлять всеми записями &#8211; пользователь может редактировать или удалять только свои записи.</p>
<p>А теперь пришло время разобраться, как это все работает.</p>
<blockquote><p>Второй демо-контроллер, описывающий работу модуля <strong>Acl</strong>, я тут показывать не буду, т.к. он гораздо менее информативен. После прочтения данной статьи Вы можете проанализировать его самостоятельно.</p></blockquote>
<h2>A1: аутентификация</h2>
<p>Если Вы знакомы с модулем <strong>Auth</strong>, то все здесь будет понятно. Библиотека <strong>A1</strong> предоставляет базовые методы <em>login()</em>, <em>logout()</em> и <em>get_user()</em>. Все знакомо. Настройка библиотеки хранится в конфигурационном файле (его имя передается в конструктор, по умолчанию &#8216;<em>a1</em>&#8216;). Там тоже все более-менее понятно, новым для нас будет ключ &#8216;<em>columns</em>&#8216;:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Table column names
 */</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'columns'</span><span style="color: #009900;">&#93;</span>   <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'username'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'username'</span><span style="color: #339933;">,</span>    <span style="color: #666666; font-style: italic;">//username</span>
	<span style="color: #0000ff;">'password'</span>	<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'password'</span><span style="color: #339933;">,</span>    <span style="color: #666666; font-style: italic;">//password</span>
	<span style="color: #0000ff;">'token'</span>    	<span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'token'</span><span style="color: #339933;">,</span>  			<span style="color: #666666; font-style: italic;">//token</span>
	<span style="color: #0000ff;">'last_login'</span><span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'last_login'</span><span style="color: #339933;">,</span>  <span style="color: #666666; font-style: italic;">//last login (optional)</span>
	<span style="color: #0000ff;">'logins'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'logins'</span> 			<span style="color: #666666; font-style: italic;">//login count (optional)</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code><br />
Как понятно из названия, тут описываются имена столбцов в БД. Из обязательных только первые три (если не планируется использовать &#8220;запоминание&#8221; пользователей, то и &#8216;<em>token</em>&#8216; не нужен). Это нужно для совместимости со сторонними таблицами пользователей.</p>
<p>В модуле определена абстрактная модель <strong>A1_User</strong>, от которой необходимо будет наследовать модель для реальной таблицы пользователей (по аналогии с <strong>Auth</strong>, там была абстрактная модель <strong>Auth_User</strong>). Имя модели пользователя указывается в параметре &#8216;<em>user_model</em>&#8216; (по умолчанию конечно же &#8216;<em>user</em>&#8216;).</p>
<h2>Acl: списки управления доступом</h2>
<p>Библиотека <strong>Acl</strong> пришла в <strong>Kohana</strong> из фреймворка <a href="http://framework.zend.com/manual/ru/zend.acl.html"><strong>Zend</strong></a> и предполагает работу с тремя базовыми терминами: роль, ресурс и действие. Например, в условии &#8220;редактирование администратором записи в блоге&#8221; ролью будет &#8216;<em>admin</em>&#8216;, действием &#8211; &#8216;<em>edit</em>&#8216; (редактирование), а ресурсом &#8211; запись в блоге (&#8216;<em>blog</em>&#8216;). Термины абстрактны, т.е. под записью в блоге будет рассматриваться любая запись, независимо от условий ее создания (автор, дата и т.д.), а под ролью &#8216;<em>admin</em>&#8216; &#8211; любой пользователь с данной ролью. Данные три термина объединяются в правила, которые определяют порядок взаимодействия с ресурсами. При этом все, что не разрешено &#8211; запрещено.</p>
<p>Сперва объявляем известные нам роли и ресурсы:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// создаем объект Acl</span>
<span style="color: #000088;">$acl</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Acl<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// добавляем роли</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_role</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'guest'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// гость</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_role</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// пользователь</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_role</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// администратор</span>
<span style="color: #666666; font-style: italic;">// добавляем ресурсы</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_resource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'blog'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// блог</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_resource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comment'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// комментарий</span></pre></div></div>

<p></code></p>
<p>Правила добавляются с помощью методов <em>allow()</em> и <em>deny()</em> объекта <strong>Acl</strong>:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// изначально все запрещено</span>
<span style="color: #666666; font-style: italic;">// писать необязательно, привел для примера</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">deny</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//  все могут читать все</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'read'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// пользователь и админ могут писать комментарии</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'admin'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// админ может писать в блог</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code><br />
В правилах сперва указывается роль (или массив ролей), затем ресурс (или ресурсы), потом &#8211; действие (действия). Вместо перечисления всех ролей/ресурсов/действий можно указать <strong>NULL</strong> (так мы дали права на чтение в примере выше). Есть еще и четвертый параметр, но о нем поговорим отдельно.</p>
<blockquote><p>Поскольку по умолчанию все запрещено, мы идем по пути &#8220;добавляем все, что можно&#8221;. Другой вариант &#8211; можно разрешить все (<code>$acl->allow(NULL, NULL, NULL)</code>), а затем добавить запрещающие правила. Главный минус &#8211; потом можно легко об этом забыть и оставить дыры в защите.</p></blockquote>
<p>Проверяем права доступа:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">is_allowed</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'guest'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// false</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">is_allowed</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// true</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">is_allowed</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// true</span></pre></div></div>

<p></code></p>
<h3>Использование иерархии</h3>
<p>Перечисление всех имеющихся ролей и ресурсов при добавлении правил может превратиться в весьма утомительное занятие. Поэтому библиотека предоставляет возможность построения иерархий с наследованием правил от предка к потомку. Давайте переделаем вышеописанный пример:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// создаем объект Acl</span>
<span style="color: #000088;">$acl</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Acl<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// добавляем роли</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_role</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'guest'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// гость</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_role</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'guest'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// пользователь</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_role</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'user'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// администратор</span>
<span style="color: #666666; font-style: italic;">// добавляем ресурсы</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_resource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// абстрактный ресурс</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_resource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// блог</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add_resource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'text'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// комментарий</span></pre></div></div>

<p></code><br />
 Как видно, была построена иерархия ролей (гость -> пользователь -> админ) и ресурсов (текст -> блог и текст -> коммент). Теперь все правила, примененные для гостя, будут доступны и пользователю с админом, а правила для текста могут быть использованы блогом и комментарием. Соответственно так теперь будем добавлять правила:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//  все могут читать все</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'guest'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'text'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'read'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// пользователь и админ могут писать комментарии</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// админ может писать в блог</span>
<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code><br />
Если в правиле указан предок, потомков можно убирать (наследование в чистом виде). В первом правиле я заменил <strong>NULL</strong> на &#8216;<em>text</em>&#8216; &#8211; результат тот же, но само правило более четкое. Например, если добавится новый ресурс &#8216;<em>stats</em>&#8216;, который должен быть разрешен только администраторам, общее правило с <strong>NULL</strong> позволит любому пользователю получить доступ. В общем, не ленитесь уточнять правила, чтобы потом после разрастания проекта это где-нибудь не аукнулось.</p>
<h3>Проверка объектов</h3>
<p>До этого мы говорили про абстрактные ресурсы и роли (в виде строк). Однако библиотека поддерживает передачу объектов, например можно использовать что-то вроде <code>$acl->is_allowed($user,  'comment', 'write');</code> В этом случае объект <em>$user</em> (в данном случае имелся в виду экземпляр <strong>ORM</strong>-модели <strong>User_Model</strong>) должен реализовывать интерфейс <em>Acl_Role_Interface</em>, что заключается в наличии метода <em>get_role_id()</em>:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> User_Model <span style="color: #000000; font-weight: bold;">extends</span> A1_User_Model implements Acl_Role_Interface <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> get_role_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span><span style="color: #666666; font-style: italic;">// мы должны вернуть значение роли</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">role</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p>В данном случае возвращается значение поля <em>role</em>, т.к. оно присутствует в реализации библиотеки <strong>A1</strong>. Если говорить про <strong>Auth</strong>, там пришлось бы возвращать массив ролей из таблицы <em>roles</em>. Аналогично можно передавать ресурсы, только для них интерфейс называется <em>Acl_Resource_Interface</em>, а необходимый метод &#8211; <em>get_resource_id()</em>.</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Blog_Model <span style="color: #000000; font-weight: bold;">extends</span> ORM implements Acl_Resource_Interface <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> get_resource_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<h3>Assertions</h3>
<p>Казалось бы, зачем нам все эти сложности с передачей объектов, если правила <strong>Acl</strong> поддерживают только абстрактные строки? И вот тут на сцену выходят т.н. <em>assertions</em> (что-то вроде триггеров, дальше я буду использовать именно такой термин). Данные триггеры позволяют совершать дополнительные проверки с полученными объектами. Вот как реализовывается разрешение редактирования собственных комментов пользователем:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'edit'</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Acl_Assert_Argument'</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'user_id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p> </code><br />
В результате при проверке <code>$acl->is_allowed($user, $comment, 'edit')</code> будет выполнена проверка на равенство <code>$user->id</code> и <code>$comment->user_id</code> (т.е. на принадлежность комментария текущему пользователю). <em>Acl_Assert_Argument</em> &#8211; это имеющийся в модуле <strong>Acl</strong> класс, позволяющий связывать между собой поля из моделей роли (в данном случае это модель <strong>User_Model</strong>, поле <em>id</em>) и ресурса (<strong>Comment_Model</strong>, поле <em>user_id</em>). Имена полей передаются в виде массива после имени класса. Можно использовать несколько связок, например так:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'edit'</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Acl_Assert_Argument'</span><span style="color: #339933;">,</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'user_id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'something_else'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'other_field'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p> </code><br />
Если все пары полей равны между собой, проверка вернет <strong>TRUE</strong> и доступ будет получен.</p>
<p>Конечно, это очень простой пример триггера, который не может решить всех проблем. Давайте попробуем реализовать простую проверку &#8211; создавать блог может только пользователь с количеством комментариев больше 100.</p>
<p><strong>1</strong>. Каждый класс-триггер должен реализовывать интерфейс <em>Acl_Assert_Interface</em>. Это заключается в необходимости реализовать метод <em>assert()</em>, объявленный в интерфейсе следующим образом:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>Acl <span style="color: #000088;">$acl</span><span style="color: #339933;">,</span> <span style="color: #000088;">$role</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$resource</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$privilege</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code><br />
Собственно говоря, данный метод как раз и вызывается при проверке правила. Таким образом, получим первый шаг на пути к созданию триггера:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Acl_Assert_Comments implements Acl_Assert_Interface <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>Acl <span style="color: #000088;">$acl</span><span style="color: #339933;">,</span> <span style="color: #000088;">$role</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$resource</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$privilege</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code><br />
<strong>2</strong>.Если необходимо предварительно настроить триггер (в примере выше сперва должны были быть созданы соответствия пар полей из объектов роли и ресурса), используем конструктор. При создании правила, как мы помним, передается дополнительный параметр, который мы и будем обрабатывать:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Acl_Assert_Comments implements Acl_Assert_Interface <span style="color: #009900;">&#123;</span>
&nbsp;
	protected <span style="color: #000088;">$comments_required</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span> AND <span style="color: #000088;">$arguments</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$arguments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comments_required</span> <span style="color: #339933;">=</span> <span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>Acl <span style="color: #000088;">$acl</span><span style="color: #339933;">,</span> <span style="color: #000088;">$role</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$resource</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$privilege</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code><br />
Мы сохраняем переданное в конструктор значение (количество комментариев для ведения записей в блоге) в свойстве <em>$comments_required</em>. Далее в методе <em>assert()</em> оно будет использовано.<br />
<strong>3</strong>. Осталось только реализовать сравнение количества комментов у пользователя с сохраненным значением:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Acl_Assert_Comments implements Acl_Assert_Interface <span style="color: #009900;">&#123;</span>
&nbsp;
	protected <span style="color: #000088;">$comments_required</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span> AND <span style="color: #000088;">$arguments</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$arguments</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comments_required</span> <span style="color: #339933;">=</span> <span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$arguments</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> <span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span>Acl <span style="color: #000088;">$acl</span><span style="color: #339933;">,</span> <span style="color: #000088;">$role</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$resource</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$privilege</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
	    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$role</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comment_count</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">comments_required</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">TRUE</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<blockquote><p>В данном примере поле <em>comment_count</em> присутствует в таблице <em>users</em>, так как я стараюсь избавиться от регулярного пересчета подобных статистических данных. Естественно, никто не мешает использовать что-то вроде <code>$role->comments->count()</code>.</p></blockquote>
<p><strong>4</strong>. Вот и все, триггер создан и работает &#8211; можете проверять. Добавление правила будет выглядеть так:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">	<span style="color: #000088;">$acl</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span>  <span style="color: #000000; font-weight: bold;">new</span> Acl_Assert_Comments<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<h2>A2</h2>
<p>По сути рассмотренные выше классы <strong>A1</strong> и <strong>Acl</strong> между собой никак не свзяаны &#8211; один отвечает за &#8220;узнавание&#8221; пользователя, а второй &#8220;ставит его на место&#8221;. Для удобства работы с ними был создан класс-обертка <strong>A2</strong>. Он является потомком класса <strong>Acl</strong> и имеет все те же методы для работы с правилами. В качестве дополнения он агрегирует объект <strong>A1</strong>, что позволяет работать с текущим пользователем напрямую.<br />
Какие методы нам предоставляет класс <strong>A2</strong>:<br />
<strong>1</strong>. Разнообразные варианты создания объекта ( <em>__construct()</em>, <em>factory()</em> и <em>instance()</em> ). Все они принимают в качестве единственного параметра <em>$config_name</em> &#8211; имя файла конфигурации (об этом чуть ниже).<br />
2. Методы для работы с объектом <strong>A1</strong>.<br />
2.1. Метод <em>logged_in()</em> перенаправляет вызов к объекту <strong>A1</strong>, в результате получаем проверку залогиненности пользователя.<br />
2.2. Метод <em>get_user()</em> таким же макаром возвращает сам объект модели пользователя (обычно это <strong>User_Model</strong>).<br />
3. Метод <code>allowed($resource = NULL, $privilige = NULL)</code> проверяет, может ли текущий пользователь иметь возможность применить к ресурсу <em>$resource</em> действие <em>$privilige</em>. Таким образом, можно не передавать вручную в объект <strong>Acl</strong> пользователя, а использовать вот такую сокращенную запись.</p>
<h3>Конфигурация</h3>
<p>Самое интересное, что наверняка бросилось в глаза &#8211; наличие некого параметра <em>$config_name</em> в конструкторе. Да-да, можно не прописывать правила, роли и ресурсы в контроллере, а использовать заранее сохраненные настройки. Вот так вот будут выглядеть настройки, описанные нами выше:<br />
 <code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'roles'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'user'</span>			<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">'guest'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'admin'</span>			<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">'user'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'guest_role'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'guest'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'resources'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'text'</span>			<span style="color: #339933;">=&gt;</span>	<span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'blog'</span>			<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">'text'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'comment'</span>		<span style="color: #339933;">=&gt;</span>	<span style="color: #0000ff;">'text'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'rules'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'allow'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span>
	<span style="color: #009900;">&#40;</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'guest'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'text'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'read'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'comment'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'write'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Acl_Assert_Comments'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code><br />
Все довольно просто и понятно. Параметр <code>$config['guest_role']</code> определяет имя роли, которая будет использоваться, если никто не залогился. Есть еще один дополнительный параметр, определяющий библиотеку для работы с аутентификацией (я говорил про <strong>A1</strong>, но ведь и <strong>Auth</strong> никто не отменял):<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'a1'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'A1'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code><br />
Если планируется использование другой библиотеки, то необходимо убедиться, что она реализует метод <em>get_user()</em> для получения текущего пользователя, а также использует шаблон <strong>Singleton</strong> &#8211; т.е. имеет статический метод <em>instance()</em>. В качестве параметра после имени библиотеки можно указать аргументы для передачи в метод <em>instance()</em>, обычно это имя конфигурации библиотеки. Сам объект будет сохранен в свойстве <em>$a1</em> (оно объявлено как <em>public</em>).</p>
<h2>Постскриптум</h2>
<p>Вот собственно и все. В использовании <strong>A2</strong> похожа на <strong>Acl</strong>, дополнительные возможности я указал. Самая неочевидная ошибка, на которую сам неоднократно напарывался &#8211; частенько забывал в моделях ролей и ресурсов реализовывать интерфейсы <em>Acl_Role_Interface</em> и <em>Acl_Resource_Interface</em> &#8211; они должны возвращать имя соответственно текущей роли (метод <em>get_role_id()</em>) или ресурса (<em>get_resource_id()</em>).</p>

<div class="bookmarkz"><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a> <a href="http://digg.com/submit?url=http://brotkin.ru/2009/09/01/a1-a2-acl/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a> <a href="http://reddit.com/submit?url=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a> <a href="http://del.icio.us/post?url=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/delicious.png" border="0" width="16" height="16" alt="del.icio.us" title="del.icio.us"></a> <a href="http://ma.gnolia.com/beta/bookmarklet/add?url=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web&description=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/magnolia.png" border="0" width="16" height="16" alt="Ma.gnolia" title="Ma.gnolia"></a> <a href="http://www.technorati.com/faves?add=http://brotkin.ru/2009/09/01/a1-a2-acl/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a> <a href="http://www.slashdot.org/bookmark.pl?url=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/slashdot.png" border="0" width="16" height="16" alt="Slashdot" title="Slashdot"></a> <a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://brotkin.ru/2009/09/01/a1-a2-acl/&t=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a> <a href="http://news2.ru/add_story.php?url=http://brotkin.ru/2009/09/01/a1-a2-acl/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a> <a href="http://www.bobrdobr.ru/addext.html?url=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a> <a href="http://rumarkz.ru/bookmarks/?action=add&popup=1&address=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/rumarkz.png" border="0" width="16" height="16" alt="RUmarkz" title="RUmarkz"></a> <a href="http://www.vaau.ru/submit/?action=step2&url=http://brotkin.ru/2009/09/01/a1-a2-acl/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/vaau.png" border="0" width="16" height="16" alt="Ваау!" title="Ваау!"></a> <a href="http://memori.ru/link/?sm=1&u_data[url]=http://brotkin.ru/2009/09/01/a1-a2-acl/&u_data[name]=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a> <a href="http://www.rucity.com/bookmarks.php?action=add&address=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a> <a href="http://moemesto.ru/post.php?url=http://brotkin.ru/2009/09/01/a1-a2-acl/&title=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/moemesto.png" border="0" width="16" height="16" alt="МоёМесто.ru" title="МоёМесто.ru"></a> <a href="http://www.mister-wong.ru/index.php?action=addurl&bm_url=http://brotkin.ru/2009/09/01/a1-a2-acl/&bm_description=A1%2FA2%2FAcl+-+%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%2C+%D1%87%D0%B5%D0%BC+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/mrwong.png" border="0" width="16" height="16" alt="Mister Wong" title="Mister Wong"></a> </div>
]]></content:encoded>
			<wfw:commentRss>http://brotkin.ru/2009/09/01/a1-a2-acl/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Своя CMS: Возвращаясь к модулю Auth</title>
		<link>http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/</link>
		<comments>http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 21:20:40 +0000</pubDate>
		<dc:creator>biakaveron</dc:creator>
				<category><![CDATA[Пишем CMS]]></category>
		<category><![CDATA[acl]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[Kohana]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://brotkin.ru/?p=183</guid>
		<description><![CDATA[Рассмотренный нами ранее модуль Auth неплох, но недавно на форуме сообщили о создании более простого модуля аутентификации с незамысловатым названием A1. Он представляет собой облегченную версию Auth &#8211; без лишней абстракции и драйверов (т.е. мы просто явно используем ORM), без ролей (точнее роли есть, но они теперь не являются отдельными от пользователя объектами). Кроме данного [...]]]></description>
			<content:encoded><![CDATA[<p>Рассмотренный нами ранее модуль <strong>Auth</strong> неплох, но недавно на форуме <a href="http://forum.kohanaphp.com/comments.php?DiscussionID=1988&#038;page=1">сообщили</a> о создании более простого модуля аутентификации с незамысловатым названием <strong>A1</strong>. Он представляет собой облегченную версию <strong>Auth</strong> &#8211; без лишней абстракции и драйверов (т.е. мы просто явно используем <strong>ORM</strong>), без ролей (точнее роли есть, но они теперь не являются отдельными от пользователя объектами). Кроме данного модуля предлагается портированная <strong>Zend</strong>&#8216;овская библиотека <strong>Zend_Acl</strong> и созданный на ее основе модуль авторизации <strong>A2</strong>.<span id="more-183"></span></p>
<p>Для начала необходимо поработать над модулями, т.к. они были созданы под 3.0 со всеми сопутствующими препятствиями (иная структура папок, именование классов и еще несколько мелочей). Итоговый архив с небольшими доработками можно скачать <a href="http://brotkin.ru/examples/kohana_tutorials/A1_Acl_A2.rar">тут</a>. Модули разбиты на три папки, но в принципе их можно объединить в одну.</p>
<h2>Настройка</h2>
<p>Скопируйте модули и контроллер в соответствующие папки. В <em>application/config/config.php</em> не забудьте подключить модули. Кроме того, рекомендую закомментировать модуль <strong>Auth</strong> и проверить, нет ли в <em>application/models</em> моделей <strong>Auth</strong> и <strong>Blog</strong> (они присутствуют в модуле <strong>A2</strong>), т.к. они будет загружены вместо необходимым нам. Для работы прилагаемого демо-контроллера необходимы две таблицы, одна для пользователей, другая для контролируемого ресурса (блоги):<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">	<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #ff0000;">`users`</span> <span style="color: #66cc66;">&#40;</span>
	  <span style="color: #ff0000;">`id`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	  <span style="color: #ff0000;">`username`</span> varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">''</span><span style="color: #66cc66;">,</span>
	  <span style="color: #ff0000;">`password`</span> char<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
	  <span style="color: #ff0000;">`logins`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'0'</span><span style="color: #66cc66;">,</span>
	  <span style="color: #ff0000;">`last_login`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
	  <span style="color: #ff0000;">`role`</span> enum<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'user'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'admin'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
	  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	  <span style="color: #993333; font-weight: bold;">UNIQUE</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`uniq_username`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`username`</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB  <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8;
&nbsp;
	<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #ff0000;">`blogs`</span> <span style="color: #66cc66;">&#40;</span>
	  <span style="color: #ff0000;">`id`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
	  <span style="color: #ff0000;">`user_id`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
	  <span style="color: #ff0000;">`text`</span> text <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
	  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
	  <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`user_id`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`user_id`</span><span style="color: #66cc66;">&#41;</span>
	<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB  <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8;</pre></div></div>

<p></code></p>
<p>Поскольку таблица с пользователями у меня уже была, я просто добавил поле `<em>role</em>` и убрал в существующем поле `<em>email</em>` атрибут <strong>NOT NULL</strong> (данное поле в демо использоваться не будет). Если таблица `<em>users</em>` у вас тоже есть, не забудьте в файле <em>modules/a1/config/a1.php</em> привести настройки (метод хэширования, &#8220;соль&#8221; и т.д.) в соответствие с теми, что были в <em>auth.php</em> (он либо в <em>application/config/</em>, либо в  <em>modules/auth/config</em>).</p>
<p>Вот собственно и все. Запускаем <em>http://localhost/a2demo/</em> и видим предложение представиться/зарегистрироваться, а также сообщение, что блогов нет. Сперва войдем на сайт под существующем логином или зарегистрируемся. Тут все более-менее похоже на модуль <strong>Auth</strong>, разве что в выводимой <strong>Profiler</strong>&#8216;ом информации на удивление мало запросов, связанных с пользователем (как мы помним, <strong>Auth</strong> делал три запроса).</p>
<h2>Управление объектами</h2>
<p>Так для чего же нам нужны эти две дополнительные библиотеки? Если вы еще не знакомы с <strong>Zend_Acl</strong>, самое время немного <a href="http://framework.zend.com/manual/ru/zend.acl.html">почитать</a>. В общих чертах, <strong>Acl</strong> (списки доступа) &#8211; это некий набор типовых правил (&#8220;разрешить то-то&#8221;/&#8221;запретить то-то&#8221;), применяемых к отдельным классам ресурсов (в нашем случае это блоги) для текущего пользователя (точнее, для имеющихся у пользователя ролей). Так, в конфигурационном файле <em>a2.php</em> приведены правила следующего вида:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'rules'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'allow'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">array</span>
	<span style="color: #009900;">&#40;</span>
			<span style="color: #666666; font-style: italic;">// guest can read blog</span>
		<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'guest'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'read'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #339933;">...</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #339933;">...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p>Первый параметр &#8211; роль, второй &#8211; класс ресурса, далее имя операции. Все это разрешается (т.к. ключ &#8220;<em>allow</em>&#8220;). Аналогично существуют правила для запрета операций. Кроме того, роли пользователей выполнены в виде иерархии <em>Гость</em>-><em>Пользователь</em>-><em>Админ</em> с наследованием правил. Еще одна возможность &#8211; использование утверждений (<strong>asserts</strong>). Это правила с добавлением условий их применения (таким образом реализована проверка владельца блога при редактировании). Все правила загружаются из файла, а не из БД, хорошо это или плохо &#8211; решать вам. Мне кажется, с разрастанием приложения могут возникнуть проблемы&#8230;</p>
<p>А что насчет <strong>A2</strong>? Дело в том, что нас не всегда устраивают разрешения для целого класса ресурсов. Для отдельных экземпляров объектов в <strong>A2</strong> можно применить отдельные правила. Для этого вместо строкового названия ресурса можно использовать экземпляр конкретного ресурса (например, <strong>ORM::factory(&#8216;blog&#8217;,1)</strong>, т.е. блог с идентификатором 1).</p>
<p>Помимо настроек в конфигурационном файле мы можем редактировать правила прямо в демо-контроллере:<br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// разрешаем редактирование всех блогов админами</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">a2</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'edit'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// добавляем для пользователей право на удаление блога с id=1</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">a2</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">allow</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'user'</span><span style="color: #339933;">,</span> ORM<span style="color: #339933;">::</span><span style="color: #004000;">factory</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'delete'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// запрещаем чтение блогов ВСЕМ пользователям (правила наследуются)</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">a2</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">deny</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'guest'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'blog'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'read'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<h2>Итог</h2>
<p>Получилось несколько сумбурно, но, надеюсь, что основную мысль я до вас донес. <img src='http://brotkin.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  В любом случае скоро нам придется попробовать применить данный модуль вместо тяжеловесного <strong>Auth</strong>. И если не выявится еще какой-либо более интересный модуль, мы будем использовать именно связку <strong>A1</strong>+<strong>A2</strong>.</p>
<p><strong>PS</strong>. В настоящее время имеется полноценная и развивающаяся версия данного модуля на <a href="http://github.com/Wouterrr/kohanamodules2.3.2/tree/master">гитхабе</a> для ветки <strong>2.3</strong>.</p>

<div class="bookmarkz"><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a> <a href="http://digg.com/submit?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a> <a href="http://reddit.com/submit?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a> <a href="http://del.icio.us/post?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/delicious.png" border="0" width="16" height="16" alt="del.icio.us" title="del.icio.us"></a> <a href="http://ma.gnolia.com/beta/bookmarklet/add?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web&description=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/magnolia.png" border="0" width="16" height="16" alt="Ma.gnolia" title="Ma.gnolia"></a> <a href="http://www.technorati.com/faves?add=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a> <a href="http://www.slashdot.org/bookmark.pl?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/slashdot.png" border="0" width="16" height="16" alt="Slashdot" title="Slashdot"></a> <a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&t=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a> <a href="http://news2.ru/add_story.php?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a> <a href="http://www.bobrdobr.ru/addext.html?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a> <a href="http://rumarkz.ru/bookmarks/?action=add&popup=1&address=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/rumarkz.png" border="0" width="16" height="16" alt="RUmarkz" title="RUmarkz"></a> <a href="http://www.vaau.ru/submit/?action=step2&url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/vaau.png" border="0" width="16" height="16" alt="Ваау!" title="Ваау!"></a> <a href="http://memori.ru/link/?sm=1&u_data[url]=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&u_data[name]=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a> <a href="http://www.rucity.com/bookmarks.php?action=add&address=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a> <a href="http://moemesto.ru/post.php?url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&title=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/moemesto.png" border="0" width="16" height="16" alt="МоёМесто.ru" title="МоёМесто.ru"></a> <a href="http://www.mister-wong.ru/index.php?action=addurl&bm_url=http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/&bm_description=%D0%A1%D0%B2%D0%BE%D1%8F+CMS%3A+%D0%92%D0%BE%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B0%D1%8F%D1%81%D1%8C+%D0%BA+%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8E+Auth+-+%D0%98%D0%B7%D1%83%D1%87%D0%B0%D0%B5%D0%BC+Web" rel="nofollow" target="_blank"><img src="http://brotkin.ru/wp-content/plugins/bookmarkz/images/mrwong.png" border="0" width="16" height="16" alt="Mister Wong" title="Mister Wong"></a> </div>
]]></content:encoded>
			<wfw:commentRss>http://brotkin.ru/2009/02/20/svoya-cms-vozvrashhayas-k-modulyu-auth/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

