Zend_Acl.xml 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15783 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.acl.introduction">
  5. <title>Introducción</title>
  6. <para>
  7. <classname>Zend_Acl</classname> provee la implementación de un sistema simple y
  8. flexible de Listas de Control de Acceso (<acronym>ACL</acronym>, por sus siglas en
  9. inglés) para la administración de privilegios. En general, una
  10. aplicación puede utilizar las <acronym>ACL</acronym> para controlar el acceso a
  11. ciertos objetos protegidos, que son requeridos por otros
  12. objetos.
  13. </para>
  14. <para>
  15. Para los propósitos de esta documentación:
  16. <itemizedlist>
  17. <listitem>
  18. <para>
  19. Un
  20. <emphasis>recurso</emphasis>
  21. es un objeto al cual el acceso esta controlado.
  22. </para>
  23. </listitem>
  24. <listitem>
  25. <para>
  26. Un
  27. <emphasis>rol</emphasis>
  28. es un objeto que puede solicitar acceso a un
  29. recurso.
  30. </para>
  31. </listitem>
  32. </itemizedlist>
  33. En términos generales,
  34. <emphasis>
  35. Los roles solicitan acceso a los recursos
  36. </emphasis>
  37. . Por ejemplo, si una persona solicita acceso a un automóvil,
  38. entonces la persona se convierte en el rol solicitante, y el
  39. automóvil en el recurso, puesto que el acceso al automóvil puede
  40. no estar disponible a cualquiera.
  41. </para>
  42. <para>
  43. A través de la especificación y uso de Listas de Control de
  44. Acceso (<acronym>ACL</acronym>), una aplicación puede controlar cómo los objetos
  45. solicitantes (roles) han obtenido acceso a objetos protegidos
  46. (recursos).
  47. </para>
  48. <sect2 id="zend.acl.introduction.resources">
  49. <title>Acerca de los Recursos</title>
  50. <para>
  51. En <classname>Zend_Acl</classname>, crear un recurso es muy sencillo. <classname>Zend_Acl</classname>
  52. proporciona el
  53. <classname>Zend_Acl_Resource_Interface</classname>
  54. para facilitar a los desarrolladores la creación de
  55. recursos. Una clase solo necesita implementar su interfaz,
  56. la cual consiste en un método único,
  57. <methodname>getResourceId()</methodname>
  58. , para que <classname>Zend_Acl</classname> considere el objeto como un recurso.
  59. Adicionalmente,
  60. <classname>Zend_Acl_Resource</classname>
  61. es proporcionado por <classname>Zend_Acl</classname> como un recurso básico de
  62. aplicación para que los desarrolladores puedan extenderla hasta
  63. donde lo deseen.
  64. </para>
  65. <para>
  66. <classname>Zend_Acl</classname> provee un estructura de árbol a la cual pueden ser
  67. agregados múltiples recursos (o "Áreas con Controles de
  68. Acceso").Ya que los recursos son almacenados en esta
  69. estructura de árbol, estos pueden ser organizados desde lo
  70. general (hacia la raíz del árbol) a lo específico (hacia las
  71. ramas del árbol). Consultas sobre un recurso específico
  72. buscarán automáticamente, en la jerarquía del
  73. recurso, reglas asignadas a recursos anteriores a los que
  74. el recurso actual haga referencia, permitiendo la herencia
  75. simple de reglas. Por ejemplo, si una regla por defecto se
  76. aplica a cada edificio en una ciudad, uno simplemente
  77. podría asignar la regla a la ciudad, en lugar de asignar la
  78. misma regla a cada edificio. Algunos edificios pueden
  79. necesitar excepciones a la regla, sin embargo, y esto es
  80. fácil de hacer en <classname>Zend_Acl</classname> asignando esta excepción a
  81. cada edificio que necesite una excepción a la regla. Un
  82. recurso sólo puede heredar de un recurso padre, aunque este
  83. recurso padre puede tener a la vez su propio recurso padre,
  84. y así; sucesivamente.
  85. </para>
  86. <para>
  87. <classname>Zend_Acl</classname> también soporta privilegios sobre recursos (ejemplo.
  88. "crear","leer","actualizar", "borrar"), y el desarrollador
  89. puede asignar reglas que afecten o a todos los privilegios o
  90. a privilegios específicos sobre un recurso.
  91. </para>
  92. </sect2>
  93. <sect2 id="zend.acl.introduction.roles">
  94. <title>Acerca de las Reglas</title>
  95. <para>
  96. Al igual que los recursos, la creación de un rol
  97. también es muy simple. <classname>Zend_Acl</classname> proporciona
  98. <classname>Zend_Acl_Role_Interface</classname>
  99. para facilitar a los desarrolladores la creación de
  100. roles. Una clase solo necesita la implementación de su
  101. interfaz, la cual consiste en un método único,
  102. <methodname>getRoleId()</methodname>
  103. , para que <classname>Zend_Acl</classname> considere que el objeto es un Rol.
  104. Adicionalmente,
  105. <classname>Zend_Acl_Role</classname>
  106. está incluido con <classname>Zend_Acl</classname> como una implementación principal
  107. del rol para que los desarrolladores la extiendan hasta
  108. donde lo deseen.
  109. </para>
  110. <para>
  111. En <classname>Zend_Acl</classname>, un Rol puede heredar de otro o más roles. Esto
  112. es para soportar herencia de reglas entre roles. Por ejemplo,
  113. un Rol de usuario, como "sally", puede estar bajo uno o más
  114. roles padre, como "editor" y "administrador". El
  115. desarrollador puede asignar reglas a "editor" y
  116. "administrador" por separado, y "sally" puede heredar tales
  117. reglas de ambos, sin tener que asignar reglas directamente a
  118. "sally".
  119. </para>
  120. <para>
  121. Dado que la habilidad de herencia desde múltiples roles es
  122. muy útil, múltiples herencias también introduce cierto grado
  123. de complejidad. El siguiente ejemplo ilustra la condición de
  124. ambiguedad y como <classname>Zend_Acl</classname> soluciona esto.
  125. </para>
  126. <example
  127. id="zend.acl.introduction.roles.example.multiple_inheritance">
  128. <title>Herencia Múlltiple entre Roles</title>
  129. <para>
  130. El siguiente código define tres roles principales - "invitado", "miembro", y "admin" - de los cuales otros roles pueden heredar. Entonces,
  131. un rol identificado como "unUsuario" es colocado y hereda de los otros tres roles. El orden en
  132. el cual estos roles aparecen en el array
  133. <varname>$parents</varname>
  134. es importante. Cuando es necesario, <classname>Zend_Acl</classname> busca por
  135. reglas de acceso definidas no solo para el rol
  136. solicitado (aquí, "unUsuario"), sino también sobre los roles heredados
  137. (aquí, "invitado", "miembro", y "admin"):
  138. </para>
  139. <programlisting language="php"><![CDATA[
  140. require_once 'Zend/Acl.php';
  141. $acl = new Zend_Acl();
  142. require_once 'Zend/Acl/Role.php';
  143. $acl->addRole(new Zend_Acl_Role('invitado'))
  144. ->addRole(new Zend_Acl_Role('miembro'))
  145. ->addRole(new Zend_Acl_Role('admin'));
  146. $parents = array('invitado', 'miembro', 'admin');
  147. $acl->addRole(new Zend_Acl_Role('unUsuario'), $parents);
  148. require_once 'Zend/Acl/Resource.php';
  149. $acl->add(new Zend_Acl_Resource('unRecurso'));
  150. $acl->deny('invitado', 'unRecurso');
  151. $acl->allow('miembro', 'unRecurso');
  152. echo $acl->isAllowed('unUsuario', 'unRecurso') ? 'permitido' : 'denegado';
  153. ]]></programlisting>
  154. <para>
  155. Ya que no hay reglas específicamente definidas para
  156. el rol "unUsuario" y "unRecurso", <classname>Zend_Acl</classname> debe buscar por reglas que puedan estar
  157. definidas para roles "unUsuario" hereda. Primero, el rol "admin" es visitado, y no hay regla de acceso definida
  158. para éste. Luego, el rol "miembro" es visitado, y <classname>Zend_Acl</classname> encuentra que aquí hay una
  159. regla especificando que "miembro" tiene permiso para acceder a "unRecurso".
  160. </para>
  161. <para>
  162. Así, <classname>Zend_Acl</classname> va a seguir examinando las reglas definidas
  163. para otros roles padre, sin embargo, encontraría que "invitado" tiene el acceso denegado a "unRecurso". Este hecho introduce una ambigüedad debido a que
  164. ahora "unUsuario" está tanto denegado como permitido para acceder a "unRecurso", por la razón de tener un conflicto de reglas
  165. heredadas de diferentes roles padre.
  166. </para>
  167. <para>
  168. <classname>Zend_Acl</classname> resuelve esta ambigüedad completando la
  169. consulta cuando encuentra la primera regla que es
  170. directamente aplicable a la consulta. En este caso, dado
  171. que el rol "miembro" es examinado antes que el rol "invitado", el código de ejemplo mostraría "permitido".
  172. </para>
  173. </example>
  174. <note>
  175. <para>
  176. Cuando se especifican múltiples padres para un Rol, se
  177. debe tener en cuenta que el último padre listado es el
  178. primero en ser buscado por reglas aplicables para una
  179. solicitud de autorización.
  180. </para>
  181. </note>
  182. </sect2>
  183. <sect2 id="zend.acl.introduction.creating">
  184. <title>Creando las Listas de Control de Acceso (<acronym>ACL</acronym>)</title>
  185. <para>
  186. Una <acronym>ACL</acronym> puede representar cualquier grupo de objetos físicos
  187. o virtuales que desee. Para propósitos de demostración,
  188. sin embargo, crearemos un <acronym>ACL</acronym> básico para un Sistema de
  189. Administración de Contenido (<acronym>CMS</acronym>) que mantendrá varias escalas de
  190. grupos sobre una amplia variedad de áreas. Para crear un
  191. nuevo objeto <acronym>ACL</acronym>, iniciamos la <acronym>ACL</acronym> sin parámetros:
  192. </para>
  193. <programlisting language="php"><![CDATA[
  194. require_once 'Zend/Acl.php';
  195. $acl = new Zend_Acl();
  196. ]]></programlisting>
  197. <note>
  198. <para>
  199. Hasta que un desarrollador especifique una regla"permitido", <classname>Zend_Acl</classname> deniega el acceso a cada privilegio
  200. sobre cada recurso para cada rol.
  201. </para>
  202. </note>
  203. </sect2>
  204. <sect2 id="zend.acl.introduction.role_registry">
  205. <title>Registrando Roles</title>
  206. <para>
  207. El Sistema de Administración de Contenido (<acronym>CMS</acronym>) casi
  208. siempre necesita una jerarquía de permisos para determinar
  209. la capacidad de identificación de sus usuarios. Puede haber
  210. un grupo de 'Invitados' para permitir acceso limitado para
  211. demostraciones, un grupo de 'Personal' para la mayoría de
  212. usuarios del CMS quienes realizan la mayor parte de
  213. operaciones del día a día, un grupo 'Editores' para las
  214. responsabilidades de publicación, revisión, archivo y
  215. eliminación de contenido, y finalmente un grupo
  216. 'Administradores' cuyas tareas pueden incluir todas las de los
  217. otros grupos y también el mantenimiento de la información
  218. delicada, manejo de usuarios, configuración de los datos
  219. básicos y su respaldo/exportación. Este grupo de permisos
  220. pueden ser representados en un registro de roles,
  221. permitiendo a cada grupo heredar los privilegios de los
  222. grupos 'padre', al igual que proporcionando distintos
  223. privilegios solo para su grupo individual. Los permisos pueden
  224. ser expresados como:
  225. </para>
  226. <table
  227. id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
  228. <title>Controles de Acceso para un CMS de ejemplo</title>
  229. <tgroup cols="3">
  230. <thead>
  231. <row>
  232. <entry>Nombre</entry>
  233. <entry>Permisos Individuales</entry>
  234. <entry>Hereda permisos de</entry>
  235. </row>
  236. </thead>
  237. <tbody>
  238. <row>
  239. <entry>Invitado</entry>
  240. <entry>View</entry>
  241. <entry>N/A</entry>
  242. </row>
  243. <row>
  244. <entry>Personal</entry>
  245. <entry>Editar, Enviar, Revisar</entry>
  246. <entry>Invitado</entry>
  247. </row>
  248. <row>
  249. <entry>Editor</entry>
  250. <entry>Publicar, Archivar, Eliminar</entry>
  251. <entry>Personal</entry>
  252. </row>
  253. <row>
  254. <entry>Administrador</entry>
  255. <entry>(Todos los accesos permitidos)</entry>
  256. <entry>N/A</entry>
  257. </row>
  258. </tbody>
  259. </tgroup>
  260. </table>
  261. <para>
  262. Para este ejemplo, se usa
  263. <classname>Zend_Acl_Role</classname>
  264. , pero cualquier objeto que implemente
  265. <classname>Zend_Acl_Role_Interface</classname>
  266. es admisible. Estos grupos pueden ser agregados al registro
  267. de roles de la siguiente manera:
  268. </para>
  269. <programlisting language="php"><![CDATA[
  270. require_once 'Zend/Acl.php';
  271. $acl = new Zend_Acl();
  272. // Agregar grupos al registro de roles usando <classname>Zend_Acl</classname>_Role
  273. require_once 'Zend/Acl/Role.php';
  274. // Invitado no hereda controles de acceso
  275. $rolInvitado = new Zend_Acl_Role('invitado');
  276. $acl->addRole($rolInvitado);
  277. // Personal hereda de Invitado
  278. $acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
  279. /* alternativamente, lo de arriba puede ser escrito así:
  280. $rolInvitado = $acl->addRole(new Zend_Acl_Role('personal'), 'invitado');
  281. //*/
  282. // Editor hereda desde personal
  283. $acl->addRole(new Zend_Acl_Role('editor'), 'personal');
  284. // Administrador no hereda controles de acceso
  285. $acl->addRole(new Zend_Acl_Role('administrador'));
  286. ]]></programlisting>
  287. </sect2>
  288. <sect2 id="zend.acl.introduction.defining">
  289. <title>Definiendo Controles de Acceso</title>
  290. <para>
  291. Ahora que la <acronym>ACL</acronym> contiene los roles relevantes, se pueden
  292. establecer reglas que definan cómo los roles pueden acceder
  293. a los recursos. Tenga en cuenta que no definiremos ningún
  294. recurso en particular para este ejemplo, el cual está
  295. simplificado para ilustrar que las reglas se aplican a todos
  296. los recursos. <classname>Zend_Acl</classname> proporciona una forma práctica por la
  297. cual las reglas solo necesitan ser asignadas de lo general a
  298. lo especifico, minimizando el número de reglas necesarias,
  299. porque los recursos y roles heredan reglas que están
  300. definidas en sus padres.
  301. </para>
  302. <para>
  303. Consecuentemente, podemos definir un grupo razonablemente
  304. complejo de reglas con un mínimo de código. Para aplicar
  305. estos permisos básicos como están definidos arriba:
  306. </para>
  307. <programlisting language="php"><![CDATA[
  308. require_once 'Zend/Acl.php';
  309. $acl = new Zend_Acl();
  310. require_once 'Zend/Acl/Role.php';
  311. $rolInvitado = new Zend_Acl_Role('invitado');
  312. $acl->addRole($rolInvitado);
  313. $acl->addRole(new Zend_Acl_Role('personal'), $rolInvitado);
  314. $acl->addRole(new Zend_Acl_Role('editor'), 'personal');
  315. $acl->addRole(new Zend_Acl_Role('administrador'));
  316. // Invitado solo puede ver el contenido
  317. $acl->allow($rolInvitado, null, 'ver');
  318. /* Lo de arriba puede ser escrito de la siguiente forma alternativa:
  319. $acl->allow('invitado', null, 'ver');
  320. //*/
  321. // Personal hereda el privilegio de ver de invitado, pero también necesita privilegios adicionales
  322. $acl->allow('personal', null, array('editar', 'enviar', 'revisar'));
  323. // Editor hereda los privilegios de ver, editar, enviar, y revisar de personal,
  324. // pero también necesita privilegios adicionales
  325. $acl->allow('editor', null, array('publicar', 'archivar', 'eliminar'));
  326. // Administrador no hereda nada, pero tiene todos los privilegios permitidos
  327. $acl->allow('administrador');
  328. ]]></programlisting>
  329. <para>
  330. El valor
  331. <constant>NULL</constant>
  332. en las llamadas de
  333. <methodname>allow()</methodname>
  334. es usado para indicar que las reglas de permiso se aplican a
  335. todos los recursos.
  336. </para>
  337. </sect2>
  338. <sect2 id="zend.acl.introduction.querying">
  339. <title>Consultando la ACL</title>
  340. <para>
  341. Ahora tenemos una <acronym>ACL</acronym> flexible que puede ser usada para
  342. determinar qué solicitantes tienen permisos para realizar
  343. funciones a través de la aplicación web. Ejecutar
  344. consultas es la forma más simple de usar el método
  345. <methodname>isAllowed()</methodname>
  346. :
  347. </para>
  348. <programlisting language="php"><![CDATA[
  349. echo $acl->isAllowed('invitado', null, 'ver') ?
  350. "permitido" : "denegado"; // permitido
  351. echo $acl->isAllowed('personal', null, 'publicar') ?
  352. "permitido" : "denegado"; // denegado
  353. echo $acl->isAllowed('personal', null, 'revisar') ?
  354. "permitido" : "denegado"; // permitido
  355. echo $acl->isAllowed('editor', null, 'ver') ?
  356. "permitido" : "denegado";
  357. // permitido debido a la herencia de invitado
  358. echo $acl->isAllowed('editor', null, 'actualizar') ?
  359. "permitido" : "denegado";
  360. // denegado debido a que no hay regla de permiso para 'actualizar'
  361. echo $acl->isAllowed('administrador', null, 'ver') ?
  362. "permitido" : "denegado";
  363. // permitido porque administrador tiene permitidos todos los privilegios
  364. echo $acl->isAllowed('administrador') ?
  365. "permitido" : "denegado";
  366. // permitido porque administrador tiene permitidos todos los privilegios
  367. echo $acl->isAllowed('administrador', null, 'actualizar') ?
  368. "permitido" : "denegado";
  369. // permitido porque administrador tiene permitidos todos los privilegios
  370. ]]></programlisting>
  371. </sect2>
  372. </sect1>
  373. <!--
  374. vim:se ts=4 sw=4 et:
  375. -->