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