Zend_Acl.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.acl.introduction">
  4. <title>Wprowadzenie</title>
  5. <para>
  6. <classname>Zend_Acl</classname> zapewnia lekką i elastyczną obsługę
  7. implementacji list kontroli dostępu (<acronym>ACL</acronym>) do zarządzania
  8. uprawnieniami. Ogólnie rzecz biorąc, aplikacja może używać list
  9. <acronym>ACL</acronym> do kontrolowania dostępu do określonych chronionych
  10. obiektów przez inne obiekty.
  11. </para>
  12. <para>
  13. Dla celów tej dokumentacji:
  14. </para>
  15. <itemizedlist>
  16. <listitem>
  17. <para>
  18. <emphasis>zasób</emphasis> jest obiektem do
  19. którego dostęp jest kontrolowany.
  20. </para>
  21. </listitem>
  22. <listitem>
  23. <para>
  24. <emphasis>rola</emphasis> jest obiektem, który
  25. może zażądać dostępu do zasobu.
  26. </para>
  27. </listitem>
  28. </itemizedlist>
  29. <para>
  30. Przystępnie mówiąc, <emphasis>role żądają dostępu do zasobów</emphasis>.
  31. Na przykład, jeśli obsługujący parking samochodow zażąda dostępu do
  32. samochodu, to ta osoba jest rolą, a samochód jest zasobem, więc dostęp
  33. do samochodu nie musi zostać przyznany każdemu.
  34. </para>
  35. <para>
  36. Dzięki określeniu i użyciu list kontroli dostępu (<acronym>ACL</acronym>),
  37. aplikacja może kontrolować to, w jaki sposób żądające obiekty (role) mają
  38. przydzielany dostęp do chronionych obiektów (zasobów).
  39. </para>
  40. <sect2 id="zend.acl.introduction.resources">
  41. <title>O zasobach</title>
  42. <para>
  43. Tworzenie zasobu w Zend_Acl jest bardzo proste. <classname>Zend_Acl</classname> zapewnia
  44. interfejs <classname>Zend_Acl_Resource_Interface</classname> aby ułatwić
  45. programistom tworzenie zasobów w aplikacji. Klasa jedynie implementuje ten
  46. interfejs, który składa się z jednej metody, <methodname>getResourceId()</methodname>,
  47. dzięki ktorej <classname>Zend_Acl</classname> wie, że obiekt jest zasobem. Dodatkowo w
  48. <classname>Zend_Acl</classname> dołączona jest klasa <classname>Zend_Acl_Resource</classname>,
  49. która jest podstawową implementacją zasobu do użycia przez
  50. programistów gdy jest to potrzebne.
  51. </para>
  52. <para>
  53. <classname>Zend_Acl</classname> zapewnia drzewiastą strukturę, w której
  54. mogą być dodawane zasoby (lub inaczej "obszary będące pod kontrolą").
  55. Dzięki temu, że zasoby są przechowywane w strukturze drzewiastej, mogą
  56. być one organizowane od ogólnych (od korzeni) do szczegółowych (do gałęzi).
  57. Zapytanie do konkretnego zasobu automatycznie przeszuka całą
  58. hierarchię zasobów, dla reguł przypisanych do przodka zasobów,
  59. pozwalając na proste dziedziczenie reguł. Na przykład, jeśli
  60. domyślna reguła ma być zastosowana do każdego budynku w mieście,
  61. wystarczy przypisać regułę do miasta, zamiast przypisywać regułę to
  62. każdego z budynków z osobna. Niektóre z budynków mogą wymagać
  63. wyjątków od tej reguły i może być to osiągnięte w łatwy sposób w
  64. <classname>Zend_Acl</classname> poprzez przypisanie takiej wyjątkowej reguły dla każdego z
  65. budynków wymagających wyjątku. Zasób może dziedziczyć tylko od
  66. jednego zasobu rodzica, a ten rodzic może także dziedziczyć tylko od
  67. jednego zasobu itd.
  68. </para>
  69. <para>
  70. <classname>Zend_Acl</classname> także obsługuje przywileje dla zasobów
  71. (np., "create", "read", "update", "delete") i programista może przypisać
  72. reguły, które mają zastosowanie do wszystkich przywilejów, lub dla
  73. konkretnych przywilejów dla jednego lub więcej zasobów.
  74. </para>
  75. </sect2>
  76. <sect2 id="zend.acl.introduction.roles">
  77. <title>O rolach</title>
  78. <para>
  79. Tak jak tworzenie zasobów, tworzenie ról także jest bardzo proste.
  80. Wszystkie role muszą implementować interfejs <classname>Zend_Acl_Role_Interface</classname>
  81. Ten interfejs składa się z jednej metody, <methodname>getRoleId()</methodname>,
  82. dzięki ktorej Zend_Acl wie, że obiekt jest rolą. Dodatkowo w
  83. Zend_Acl dołączona jest klasa <classname>Zend_Acl_Role</classname>,
  84. która jest podstawową implementacją roli do użycia przez
  85. programistów gdy jest to potrzebne.
  86. </para>
  87. <para>
  88. W <classname>Zend_Acl</classname> rola może dziedziczyć z jednej lub więcej ról. Jest to po
  89. to, aby możliwe było dziedziczenie zasad dla ról. Na przykład rola,
  90. użytkownik "sally", może dziedziczyć z jednej lub więcej ról
  91. rodziców, takich jak na przykład "editor" oraz "administrator".
  92. Programista może przypisać reguły dla ról "editor" oraz
  93. "administrator" osobno, a "sally" będzie dziedziczyć te reguły od
  94. obu ról, bez konieczności przypisania reguł bezpośrednio dla
  95. "sally".
  96. </para>
  97. <para>
  98. Chociaż możliwość dziedziczenia po wielu rolach jest bardzo
  99. użyteczna, to takie dziedziczenie wprowadza pewien stopień
  100. złożoności. Poniższy przykład ilustruje niejasny przypadek
  101. dziedziczenia i pokazuje w jaki sposób <classname>Zend_Acl</classname> go rozwiązuje.
  102. </para>
  103. <example id="zend.acl.introduction.roles.example.multiple_inheritance">
  104. <title>Dziedziczenie po wielu rolach</title>
  105. <para>
  106. Poniższy kod definiuje trzy podstawowe role, po których inne role
  107. mogą dziedziczyć - "guest", "member",
  108. oraz "admin". Następnie definiowana jest rola o
  109. nazwie "someUser", ktora dziedziczy po zdefiniowanych
  110. wcześniej trzech rolach. Ważna jest kolejność zdefiniowania tych
  111. trzech ról w tablicy <varname>$parents</varname>. Gdy sprawdzamy
  112. reguły dostępu, <classname>Zend_Acl</classname> szuka reguł zdefiniowanych nie tylko dla
  113. danej roli (w tym przypadku someUser"), ale także
  114. dla ról, po których ta rola dziedziczy (w tym przypadku
  115. "guest", "member" oraz "admin"):
  116. </para>
  117. <programlisting language="php"><![CDATA[
  118. $acl = new Zend_Acl();
  119. $acl->addRole(new Zend_Acl_Role('guest'))
  120. ->addRole(new Zend_Acl_Role('member'))
  121. ->addRole(new Zend_Acl_Role('admin'));
  122. $parents = array('guest', 'member', 'admin');
  123. $acl->addRole(new Zend_Acl_Role('someUser'), $parents);
  124. $acl->add(new Zend_Acl_Resource('someResource'));
  125. $acl->deny('guest', 'someResource');
  126. $acl->allow('member', 'someResource');
  127. echo $acl->isAllowed('someUser', 'someResource') ? 'allowed' : 'denied';
  128. ]]></programlisting>
  129. <para>
  130. Z tego względu, że nie ma zdefiniowanych reguł konkretnie dla
  131. roli "someUser" oraz dla zasobu "someResource",
  132. <classname>Zend_Acl</classname> musi szukać zasad, ktore mogą być zdefiniowane dla ról,
  133. po których dziedziczy rola "someUser>". Wpierw
  134. sprawdzana jest rola "admin", a dla niej nie ma
  135. zdefiniowanej żadnej reguły dostępu. Następnie sprawdzana jest
  136. rola "member" i <classname>Zend_Acl</classname> znajduje zdefiniowaną
  137. regułę zezwalająca roli "member" na dostęp do zasobu
  138. "someResource".
  139. </para>
  140. <para>
  141. Jeśli <classname>Zend_Acl</classname> kontynuowałby sprawdzanie reguł zdefiniowanych dla
  142. innych ról rodziców, znalazłby regułę zabraniającą roli
  143. "guest" dostępu do zasobu "someResource".
  144. Ten fakt wprowadza niejaność, ponieważ teraz rola
  145. "someUser" ma zarówno dozwolony jak i zabroniony
  146. dostęp do zasobu "someResource", z tego powodu, że
  147. posiada odziedziczone po dwóch rolach reguły, które są ze sobą
  148. sprzeczne.
  149. </para>
  150. <para>
  151. <classname>Zend_Acl</classname> rozwiązuje tę niejaśność kończąc
  152. zapytanie wtedy, gdy znajdzie pierwszą regułę, wprost pasującą do
  153. zapytania. W tym przypadku, z tego względu, że rola "member" jest
  154. sprawdzana przed rolą "guest", przykładowy kod
  155. wyświetliłby "allowed".
  156. </para>
  157. </example>
  158. <note>
  159. <para>
  160. Gdy określasz wielu rodziców dla roli, pamiętaj, że ostatni
  161. rodzic na liście jest pierwszym przeszukiwanym rodzicem w
  162. celu znalezienia ról pasujących do zapytania autoryzacyjnego.
  163. </para>
  164. </note>
  165. </sect2>
  166. <sect2 id="zend.acl.introduction.creating">
  167. <title>Tworzenie list kontroli dostępu</title>
  168. <para>
  169. <acronym>ACL</acronym> może reprezentować dowolny zestaw fizycznych lub wirtualnych
  170. obiektów których potrzebujesz. Dla celów prezentacji utworzymy <acronym>ACL</acronym>
  171. dla prostego Systemu Zarządzania Treścią (Content Management System
  172. - <acronym>CMS</acronym>), w którym różnymi obszarami zarządza kilka poziomów grup.
  173. Aby utworzyć nowy obiekt <acronym>ACL</acronym>, utwórzmy instancję <acronym>ACL</acronym> bez parametrów:
  174. </para>
  175. <programlisting language="php"><![CDATA[
  176. $acl = new Zend_Acl();
  177. ]]></programlisting>
  178. <note>
  179. <para>
  180. Dopóki programista nie określi reguły "allow", <classname>Zend_Acl</classname> zabroni
  181. dostępu wszystkim rolom do wszystkich przywilejów dla wszystkich
  182. zasobów.
  183. </para>
  184. </note>
  185. </sect2>
  186. <sect2 id="zend.acl.introduction.role_registry">
  187. <title>Rejestrowanie ról</title>
  188. <para>
  189. System Zarządzania Treścią prawie zawsze potrzebuje hierarchii
  190. uprawnień aby określić możliwości jego użytkowników.
  191. Może być tu grupa 'Guest' aby pozwolić na limitowany dostęp
  192. dla celów demonstracyjnych, grupa 'Staff' dla większości
  193. użytkowników aplikacji <acronym>CMS</acronym>, którzy przeprowadzają najczęstsze
  194. codzienne operacje, grupa 'Editor' dla tych odpowiedzialnych za
  195. publikowanie, przeglądanie, archiwizowanie i usuwanie zawartości i
  196. ostatecznie grupa 'Administrator', której zadania obejmują zarówno
  197. zadania wszystkich innych grup, jak i zarządzanie ważnymi
  198. informacjami, zarządzanie użytkownikami, konfigurację baz danych
  199. oraz przeprowadzanie kopii zapasowych/eksportu danych.
  200. Ten zestaw pozwoleń może być reprezentowany w rejestrze ról,
  201. pozwalając każdej grupie dziedziczyć uprawnienia z grup rodziców,
  202. a także umożliwiając każdej z grup posiadanie własnych unikalnych
  203. uprawnień. Uprawnienia mogą być wyrażone w taki sposób:
  204. </para>
  205. <table id="zend.acl.introduction.role_registry.table.example_cms_access_controls">
  206. <title>Kontrola dostępu dla przykładowego CMS</title>
  207. <tgroup cols="3">
  208. <thead>
  209. <row>
  210. <entry>Nazwa</entry>
  211. <entry>Unikalne uprawnienia</entry>
  212. <entry>Dzidziczy uprawnienia od</entry>
  213. </row>
  214. </thead>
  215. <tbody>
  216. <row>
  217. <entry>Guest</entry>
  218. <entry>View</entry>
  219. <entry>N/A</entry>
  220. </row>
  221. <row>
  222. <entry>Staff</entry>
  223. <entry>Edit, Submit, Revise</entry>
  224. <entry>Guest</entry>
  225. </row>
  226. <row>
  227. <entry>Editor</entry>
  228. <entry>Publish, Archive, Delete</entry>
  229. <entry>Staff</entry>
  230. </row>
  231. <row>
  232. <entry>Administrator</entry>
  233. <entry>(posiada cały dostęp)</entry>
  234. <entry>N/A</entry>
  235. </row>
  236. </tbody>
  237. </tgroup>
  238. </table>
  239. <para>
  240. W tym przykładzie użyty jest obiekt <classname>Zend_Acl_Role</classname>, ale
  241. dozwolony jest dowolny obiekt, który implementuje interfejs
  242. <classname>Zend_Acl_Role_Interface</classname>. Te grupy mogą być dodane
  243. do rejestru ról w taki sposób:
  244. </para>
  245. <programlisting language="php"><![CDATA[
  246. $acl = new Zend_Acl();
  247. // Dodajemy grupy do rejestru ról używając obiektu Zend_Acl_Role
  248. // Grupa guest nie dziedziczy kontroli dostępu
  249. $roleGuest = new Zend_Acl_Role('guest');
  250. $acl->addRole($roleGuest);
  251. // Grupa staff dzidziczy od grupy guest
  252. $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
  253. /*
  254. alternatywnie, powyższe mogłoby wyglądać tak:
  255. $acl->addRole(new Zend_Acl_Role('staff'), 'guest');
  256. */
  257. // Grupa editor dziedziczy od grupy staff
  258. $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
  259. // Administrator nie dziedziczy kontroli dostępu
  260. $acl->addRole(new Zend_Acl_Role('administrator'));
  261. ]]></programlisting>
  262. </sect2>
  263. <sect2 id="zend.acl.introduction.defining">
  264. <title>Definiowanie kontroli dostępu</title>
  265. <para>
  266. Teraz gdy <acronym>ACL</acronym> zawiera stosowne role, możemy ustalić reguły, które
  267. definiują w jaki sposób role mają uzyskiwać dostęp do zasobów.
  268. Mogłeś zauważyć, że nie zdefiniowaliśmy w tym przykładzie żadnych
  269. konkretnych zasobów, co jest uproszczone w celu zilustrowania, że
  270. reguły mają zastosowanie do wszystkich zasobów. <classname>Zend_Acl</classname> zapewnia
  271. implementację dzięki której reguły mogą być przypisane od ogólnych
  272. do szczegółowych, minimalizując ilość potrzebnych reguł, ponieważ
  273. zasoby oraz role dziedziczą reguły, które są definiowane dla ich
  274. przodków.
  275. </para>
  276. <note>
  277. <para>
  278. W zasadzie <classname>Zend_Acl</classname> przestrzega danej reguły tylko wtedy, gdy
  279. nie ma zastosowania bardziej szczegółowa reguła.
  280. </para>
  281. </note>
  282. <para>
  283. Możemy więc zdefiniować rozsądny kompleksowy zestaw reguł przy
  284. minimalnej ilości kodu. Aby zastosować podstawowe uprawnienia
  285. zdefiniowane wyżej zrób tak:
  286. </para>
  287. <programlisting language="php"><![CDATA[
  288. $acl = new Zend_Acl();
  289. $roleGuest = new Zend_Acl_Role('guest');
  290. $acl->addRole($roleGuest);
  291. $acl->addRole(new Zend_Acl_Role('staff'), $roleGuest);
  292. $acl->addRole(new Zend_Acl_Role('editor'), 'staff');
  293. $acl->addRole(new Zend_Acl_Role('administrator'));
  294. // Grupa guest może tylko oglądać zawartość
  295. $acl->allow($roleGuest, null, 'view');
  296. /*
  297. alternatywnie, powyższe mogłoby wyglądać tak:
  298. $acl->allow('guest', null, 'view');
  299. */
  300. // Grupa staff dzidziczy uprawnienia view od grupy guest,
  301. // ale także potrzebuje dodatkowych uprawnień
  302. $acl->allow('staff', null, array('edit', 'submit', 'revise'));
  303. // Grupa editor dziedziczy uprawnienia view, edit, submit,
  304. // oraz revise od grupy staff, ale także potrzebuje dodatkowych uprawnień
  305. $acl->allow('editor', null, array('publish', 'archive', 'delete'));
  306. // Administrator nie dziedziczy niczego, ale ma dostęp do wszystkich zasobów
  307. $acl->allow('administrator');
  308. ]]></programlisting>
  309. <para>
  310. Wartości <constant>NULL</constant> w powyższych wywołaniach metod
  311. <methodname>allow()</methodname> oznaczają, że reguły dotyczą wszystkich zasobów.
  312. </para>
  313. </sect2>
  314. <sect2 id="zend.acl.introduction.querying">
  315. <title>Zapytania ACL</title>
  316. <para>
  317. Posiadamy teraz elastyczne <acronym>ACL</acronym>, ktore mogą być użyte do określenia,
  318. czy żądająca osoba posiada uprawnienia do przeprowadzenia określonej
  319. akcji w aplikacji web. Przeprowadzenie zapytań jest bardzo proste
  320. poprzez użycie metody <methodname>isAllowed()</methodname>:
  321. </para>
  322. <programlisting language="php"><![CDATA[
  323. echo $acl->isAllowed('guest', null, 'view') ?
  324. "allowed" : "denied";
  325. // dozwolone
  326. echo $acl->isAllowed('staff', null, 'publish') ?
  327. "allowed" : "denied";
  328. // zabronione
  329. echo $acl->isAllowed('staff', null, 'revise') ?
  330. "allowed" : "denied";
  331. // dozwolone
  332. echo $acl->isAllowed('editor', null, 'view') ?
  333. "allowed" : "denied";
  334. // dozwolone ponieważ jest dziedziczone od gościa
  335. echo $acl->isAllowed('editor', null, 'update') ?
  336. "allowed" : "denied";
  337. // zabronione ponieważ nie ma reguły dla 'update'
  338. echo $acl->isAllowed('administrator', null, 'view') ?
  339. "allowed" : "denied";
  340. // dozwolone ponieważ administrator ma wszystkie uprawnienia
  341. echo $acl->isAllowed('administrator') ?
  342. "allowed" : "denied";
  343. // dozwolone ponieważ administrator ma wszystkie uprawnienia
  344. echo $acl->isAllowed('administrator', null, 'update') ?
  345. "allowed" : "denied";
  346. // dozwolone ponieważ administrator ma wszystkie uprawnienia
  347. ]]></programlisting>
  348. </sect2>
  349. </sect1>