Zend_Acl.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24249 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.acl.introduction">
  5. <title>Introdução</title>
  6. <para>
  7. <classname>Zend_Acl</classname> fornece uma implementação de lista de controle de acesso
  8. (<acronym>ACL</acronym>, na sigla em inglês) leve e flexível para a gestão privilégios.
  9. Em geral, uma aplicação pode utilizar essa <acronym>ACL</acronym> para controlar o acesso a
  10. determinados objetos protegidos por outros objetos requerentes.
  11. </para>
  12. <para>
  13. Para o propósito desta documentação:
  14. </para>
  15. <itemizedlist>
  16. <listitem>
  17. <para>
  18. Um <emphasis>recurso</emphasis> é um objeto cujo acesso é controlado
  19. </para>
  20. </listitem>
  21. <listitem>
  22. <para>
  23. Um <emphasis>papel</emphasis> é um objeto que pode solicitar acesso a um Recurso.
  24. </para>
  25. </listitem>
  26. </itemizedlist>
  27. <para>
  28. De modo simples, <emphasis>papéis requisitam acesso a recursos</emphasis>. Por exemplo, se
  29. um atendente de estacionamento solicita acesso ao um carro, o atendente é o papel
  30. requisitante e o carro é o recurso, pois o acesso ao carro pode não ser garantido a qualquer
  31. um.
  32. </para>
  33. <para>
  34. Através da especificação e uso de uma <acronym>ACL</acronym>, uma aplicação pode controlar
  35. como os papéis têm acesso aos recursos.
  36. </para>
  37. <sect2 id="zend.acl.introduction.resources">
  38. <title>Recursos</title>
  39. <para>
  40. A criação de um recurso em <classname>Zend_Acl</classname> é muito simples.
  41. <classname>Zend_Acl</classname> fornece um meio,
  42. <classname>Zend_Acl_Resource_Interface</classname>, para facilitar a criação de recursos
  43. em uma aplicação. Uma classe precisa apenas implementar esta interface, que consiste em
  44. um único método, <methodname>getResourceId()</methodname>, para que
  45. <classname>Zend_Acl</classname> reconheça o objeto como um recurso. Adicionalmente,
  46. <classname>Zend_Acl_Resource</classname> é fornecida por <classname>Zend_Acl</classname>
  47. como uma implementação básica de recurso para que desenvolvedores a extendam conforme
  48. necessário.
  49. </para>
  50. <para>
  51. <classname>Zend_Acl</classname> fornece uma estrutura de árvore na qual múltiplos
  52. recursos podem ser adicionados. Como os recursos são armazenados em uma estrutura de
  53. árvore, eles podem ser organizados do geral (em direção à raiz da árvore) para o
  54. específico (em direção às folhas da árvore). Consultas em um recurso específico irá
  55. automaticamente pesquisar sua hierarquia por regras definidas em recursos ancenstrais,
  56. permitindo herança simplificada de regras. Por exemplo, se uma regra deve ser aplicada a
  57. cada construção em uma cidade, pode-se simplesmente aplicar a regra à cidade, ao invés
  58. de atribuir a mesma regra para cada construção. Contudo, algumas construções podem
  59. necessitar de exceções para tal regra e isto pode ser feito em
  60. <classname>Zend_Acl</classname> atribuindo tal exceção a cada construção que a
  61. necessite. Um recurso pode descender de apenas um recurso pai, embora este recurso pai
  62. pode possuir seu próprio pai, etc.
  63. </para>
  64. <para>
  65. <classname>Zend_Acl</classname> também suporta privilégios em recursos (ex., "criar",
  66. "ler", "atualizar", "excluir") e o desenvolvedor pode atribuir regras que afetam todos
  67. os privilégios ou apenas privilégios específicos em um ou mais recursos.
  68. </para>
  69. </sect2>
  70. <sect2 id="zend.acl.introduction.roles">
  71. <title>Papéis</title>
  72. <para>
  73. Assim como recursos, criar um papel é também muito simples. Todos os papéis devem
  74. implementar <classname>Zend_Acl_Role_Interface</classname>. Esta interface consiste
  75. em um único método, <methodname>getRoleId()</methodname>. Adicionalmente,
  76. <classname>Zend_Acl_Role</classname> é fornecida por <classname>Zend_Acl</classname>
  77. como uma implementação de papel básica da qual desenvolvedores podem extender,
  78. quando necessário.
  79. </para>
  80. <para>
  81. Em <classname>Zend_Acl</classname>, um papel pode derivar de um ou mais papéis. Isto
  82. é para suportar herança de regras através de papéis. Por exemplo, um papel de usuário,
  83. tal como "sally", pode derivar de um ou mais papéis pai, como "editor" e
  84. "administrador". O desenvolvedor pode atribuir regras para "editor" e "administrador"
  85. separadamente, e "sally" herdará tais regras de ambos, sem a necessidade de atribuir
  86. regras diretamente a "sally".
  87. </para>
  88. <para>
  89. Embora a abilidade de herdaer de múltiplios papéis seja muito útil, herança múltipla
  90. também introduz algum grau de complexidade. O exemplo a seguir ilustra a condição
  91. ambígua e como <classname>Zend_Acl</classname> a soluciona.
  92. </para>
  93. <example id="zend.acl.introduction.roles.example.multiple_inheritance">
  94. <title>Herança múltipla através de Papéis</title>
  95. <para>
  96. O código a seguir define três papéis fundamentais - "visitante", "membro" e
  97. "admin" - dos quais outros papéis irão descender. Então, um papel identificado por
  98. "algumUsuario" é estabelecido e descende dos outros três papéis. A ordem em que
  99. estes papéis aparecem no array <varname>$parents</varname> é importante. Quando
  100. necessário, <classname>Zend_Acl</classname> procura por regras de acesso definidas
  101. não somente para o papél consultado (aqui, "algumUsuario"), mas também em papéis
  102. do qual o papel consultado descende (aqui, "visitante", "membro" e "admin"):
  103. </para>
  104. <programlisting language="php"><![CDATA[
  105. $acl = new Zend_Acl();
  106. $acl->addRole(new Zend_Acl_Role('visitante'))
  107. ->addRole(new Zend_Acl_Role('membro'))
  108. ->addRole(new Zend_Acl_Role('admin'));
  109. $parents = array('visitante', 'membro', 'admin');
  110. $acl->addRole(new Zend_Acl_Role('algumUsuario'), $parents);
  111. $acl->add(new Zend_Acl_Resource('algumRecurso'));
  112. $acl->deny('visitante', 'algumRecurso');
  113. $acl->allow('membro', 'algumRecurso');
  114. echo $acl->isAllowed('algumUsuario', 'algumRecurso') ? 'permitido' : 'negado';
  115. ]]></programlisting>
  116. <para>
  117. Como não há regra especificamente definida para o papel "algumUsuario" e
  118. "algumRecurso", <classname>Zend_Acl</classname> deve procurar por regras que tenham
  119. sido definidas para papéis dos quais "algumUsuario" descende. Primeiro, o papel
  120. "admin" é visitado e não há regra de acesso definida para ele. Depois, o papel
  121. "membro" é visitado e <classname>Zend_Acl</classname> verifica que há uma regra
  122. especificando que "membro" tem acesso permitido a "algumRecurso".
  123. </para>
  124. <para>
  125. Se <classname>Zend_Acl</classname> continuar examinando as regras definidas para
  126. outros papéis pai, contudo, ela encontrará que "visitante" tem acesso negado a
  127. "algumRecurso". Este é o fato que introduz uma ambiguidade, pois agora
  128. "algumUsuario" possui, ao mesmo tempo, acesso negado e permitido a "algumRecurso",
  129. pelo motivo de herdar regras conflitantes de diferentes papéis pai.
  130. </para>
  131. <para>
  132. <classname>Zend_Acl</classname> soluciona esta ambiguidade concluindo a consulta
  133. quando ela encontra a primeira regra diretamente aplicável a consulta. Neste caso,
  134. como o papel "membro" é examinado antes do papel "visitante", o código de exemplo
  135. exibirá "permitido".
  136. </para>
  137. </example>
  138. <note>
  139. <para>
  140. Quando especificando múltiplos pais para um papel, tenha em mente que o último pai
  141. listado será o primeiro buscado para regras aplicáveis a uma consulta de
  142. autorização.
  143. </para>
  144. </note>
  145. </sect2>
  146. <sect2 id="zend.acl.introduction.creating">
  147. <title>Criando Listas de Controle de Acesso</title>
  148. <para>
  149. Uma Lista de Controle de Acesso (<acronym>ACL</acronym>, na sigla em inglês) pode
  150. representar qualquer conjunto de objetos físicos ou virtuais que você desejar. Contudo,
  151. para o propósito de demonstração, criaremos uma <acronym>ACL</acronym> básica de um
  152. Sistema de Gerenciamento de Conteúdo (<acronym>CMS</acronym>, na sigla em inglês) que
  153. mentém diversas camadas de grupos através de uma grande variedade de áreas. Para criar
  154. um novo objeto <acronym>ACL</acronym>, instanciamos a <acronym>ACL</acronym> sem
  155. parâmetros:
  156. </para>
  157. <programlisting language="php"><![CDATA[
  158. $acl = new Zend_Acl();
  159. ]]></programlisting>
  160. <note>
  161. <para>
  162. A menos que um desenvolvedor especifique uma regra "allow" (permitir - em inglês),
  163. <classname>Zend_Acl</classname> negará acesso a todo privilégio em todo recurso para
  164. todo papel.
  165. </para>
  166. </note>
  167. </sect2>
  168. <sect2 id="zend.acl.introduction.role_registry">
  169. <title>Registrando Papéis</title>
  170. <para>
  171. O <acronym>CMS</acronym> irá quase sempre necessitar de uma hierarquia de permissões
  172. para determinar as capacidades de autoridade de seus usuários. Pode haver um grupo
  173. 'Visitante' para permitir acesso limitado para demonstrações, um grupo 'Equipe' para
  174. que a maioria dos usuários do <acronym>CMS</acronym> que executam grande parte das
  175. operações diárias, um grupo 'Editor' responsável pela publicação, revisão, arquivamento
  176. e exclusão de conteúdo, e finalmente um grupo 'Administrador' cujas tarefas podem
  177. incluir todas as de outros grupos bem como a manutenção de informações sensíveis,
  178. gerenciamento de usuários, configuração de back-end, dados de configuração, cópias de
  179. segurança e exportação. Este conjunto de permissões podem ser representadas em um
  180. registro de papéis, permitindo a cada grupo herdar privilégios de grupos 'pai', assim
  181. como fornecer privilégios distintos para grupos únicos. As permissões podem ser
  182. expressas como:
  183. </para>
  184. <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
  185. <title>Controles de Acesso para um CMS de Exemplo</title>
  186. <tgroup cols="3">
  187. <thead>
  188. <row>
  189. <entry>Nome</entry>
  190. <entry>Permissões Únicas</entry>
  191. <entry>Permissões herdadas de</entry>
  192. </row>
  193. </thead>
  194. <tbody>
  195. <row>
  196. <entry>Visitante</entry>
  197. <entry>Visualizar</entry>
  198. <entry>N/D</entry>
  199. </row>
  200. <row>
  201. <entry>Equipe</entry>
  202. <entry>Editar, Enviar, Revisar</entry>
  203. <entry>Visitante</entry>
  204. </row>
  205. <row>
  206. <entry>Editor</entry>
  207. <entry>Publicar, Arquivar, Excluir</entry>
  208. <entry>Equipe</entry>
  209. </row>
  210. <row>
  211. <entry>Administrador</entry>
  212. <entry>(Todos os acessos garantidos)</entry>
  213. <entry>N/D</entry>
  214. </row>
  215. </tbody>
  216. </tgroup>
  217. </table>
  218. <para>
  219. Para este exemplo, <classname>Zend_Acl_Role</classname> é usado, mas qualquer objeto
  220. que implemente <classname>Zend_Acl_Role_Interface</classname> é aceitável. Estes
  221. grupos podem ser adicionados ao registro de papéis, como a seguir:
  222. </para>
  223. <programlisting language="php"><![CDATA[
  224. $acl = new Zend_Acl();
  225. // Adiciona grupos ao registro de papéis usando Zend_Acl_Role
  226. // 'Visitante' não herda controles de acesso
  227. $roleGuest = new Zend_Acl_Role('visitante');
  228. $acl->addRole($roleGuest);
  229. // 'Equipe' descende de 'Visitante'
  230. $acl->addRole(new Zend_Acl_Role('equipe'), $roleGuest);
  231. /*
  232. Alternativamente, o código acima poderia ser escrito como:
  233. $acl->addRole(new Zend_Acl_Role('equipe'), 'visitante');
  234. */
  235. // 'Editor' descende de 'Equipe'
  236. $acl->addRole(new Zend_Acl_Role('editor'), 'equipe');
  237. // 'Administrador' não herda controles de acesso
  238. $acl->addRole(new Zend_Acl_Role('administrator'));
  239. ]]></programlisting>
  240. </sect2>
  241. <sect2 id="zend.acl.introduction.defining">
  242. <title>Definindo Controles de Acesso</title>
  243. <para>
  244. Agora que a <acronym>ACL</acronym> contém os papéis relevantes, regras podem ser
  245. estabelecidas para definir quais recursos podem ser acessados por quais papéis. Você
  246. pode notar que não definimos nenhum recurso em particular para este exemplo, que é
  247. simplificado para ilustrar que regras se aplicam a todos os recursos.
  248. <classname>Zend_Acl</classname> fornece uma implementação onde regras necessitam apenas
  249. serem atribuidas do caso geral para o específico, minimizando o número de regras
  250. necessárias, pois recursos e papéis herdam regras definidas em seus ancestrais.
  251. </para>
  252. <note>
  253. <para>
  254. Em geral, <classname>Zend_Acl</classname> obedecerá uma regra dada se e somente se
  255. uma regra mais específica não for aplicável.
  256. </para>
  257. </note>
  258. <para>
  259. Consequentemente, podemos definir um conjunto razoavelmente complexo de regras com o
  260. mínimo de código. Para aplicar as permissões básicas, tal como definido acima:
  261. </para>
  262. <programlisting language="php"><![CDATA[
  263. $acl = new Zend_Acl();
  264. $roleGuest = new Zend_Acl_Role('visitante');
  265. $acl->addRole($roleGuest);
  266. $acl->addRole(new Zend_Acl_Role('equipe'), $roleGuest);
  267. $acl->addRole(new Zend_Acl_Role('editor'), 'equipe');
  268. $acl->addRole(new Zend_Acl_Role('administrador'));
  269. // 'Visitante' pode apenas visualizar conteúdo
  270. $acl->allow($roleGuest, null, 'visualizar');
  271. /*
  272. Alternatively, the above could be written:
  273. $acl->allow('visitante', null, 'visualizar');
  274. //*/
  275. // 'Equipe' herda privilégios de 'Visitante', porém precisa de
  276. // privilégios adicionais
  277. $acl->allow('equipe', null, array('editar', 'enviar', 'revisar'));
  278. // 'Editor' herda os privilégios visualizar, editar, enviar, e revisar de
  279. // 'Equipe', mas também precisa de privilégios adicionais
  280. $acl->allow('editor', null, array('publicar', 'arquivar', 'excluir'));
  281. // Administrador não herda nada, mas têm acesso a tudo
  282. $acl->allow('administrador');
  283. ]]></programlisting>
  284. <para>
  285. Os valores <constant>NULL</constant> nas chamadas <methodname>allow()</methodname>
  286. acima indicam que as regras para permitir acesso se aplicam a todos os recursos.
  287. </para>
  288. </sect2>
  289. <sect2 id="zend.acl.introduction.querying">
  290. <title>Consultando uma ACL</title>
  291. <para>
  292. Temos agora uma <acronym>ACL</acronym> flexível que pode ser usada para determinar quais
  293. solicitantes têm permissão para executar funções através da aplicação web.
  294. Realizar consultas é bastante simples usando o método
  295. <methodname>isAllowed()</methodname>:
  296. </para>
  297. <programlisting language="php"><![CDATA[
  298. echo $acl->isAllowed('visitante', null, 'visualizar') ?
  299. "permitido" : "negado";
  300. // permitido
  301. echo $acl->isAllowed('equipe', null, 'publicar') ?
  302. "permitido" : "negado";
  303. // negado
  304. echo $acl->isAllowed('equipe', null, 'revisar') ?
  305. "permitido" : "negado";
  306. // permitido
  307. echo $acl->isAllowed('editor', null, 'visualizar') ?
  308. "permitido" : "negado";
  309. // 'permitido' por conta da herança de 'visitante'
  310. echo $acl->isAllowed('editor', null, 'atualizar') ?
  311. "permitido" : "negado";
  312. // 'negado' pois não há regra 'atualizar'
  313. echo $acl->isAllowed('administrador', null, 'visualizar') ?
  314. "permitido" : "negado";
  315. // permitido, pois administrador é permitido a todos os privilégios
  316. echo $acl->isAllowed('administrador') ?
  317. "permitido" : "negado";
  318. // permitido, pois administrador é permitido a todos os privilégios
  319. echo $acl->isAllowed('administrador', null, 'atualizar') ?
  320. "permitido" : "negado";
  321. // permitido, pois administrador é permitido a todos os privilégios
  322. ]]></programlisting>
  323. </sect2>
  324. </sect1>
  325. <!--
  326. vim:se ts=4 sw=4 et:
  327. -->