Miałeś już okazję zapoznać się na naszych łamach z kilkoma modułami Zend Frameworka. Dziś poznasz kolejny z nich – Zend ACL, który pozwala on na zarządzanie prawami dostępu.
Aby korzystać z Zend_ACL, nie musisz używać co
prawda innych modułów Zend Frameworka. Warto
jednak poznać przynajmniej te podstawowe moduły,
ponieważ bardzo ułatwia to pracę nad projektami.
Zasoby i role
W dużym skrócie, Zend_ACL pozwala na zarządzanie
prawami dostępu do zasobów. Co to oznacza?
Wyobraźmy sobie następującą sytuację. Mamy
do dyspozycji prosty system newsów, a w nim dwa
rodzaje użytkowników – czytelnik i administrator.
Czytelnik może jedynie czytać newsy. Administrator
może je tworzyć, edytować oraz usuwać. Ale… Nie
chcemy, aby każdy, kto może tworzyć newsy, mógł
je także usuwać. Musimy więc mieć możliwość
nadawania uprawnień poszczególnym użytkownikom.
I tu właśnie z pomocą przychodzi Zend_ACL.
Zanim zajmiemy się omawianiem Zend_ACL, należy
wyjaśnić czym są role (Role) i zasoby (Resource).
Na szczęście nie jest to trudne:
- zasoby są obiektami (działaniami, zasobami,
itd.), do których dostęp ma być kontrolowany, - role to obiekty (użytkownicy, obiekty itd.), które
żądają dostępu do zasobów.
Tak więc, możemy mieć role: czytelnik, redaktor,
administrator, oraz zasoby: newsy, artykuły. Na nich
można przeprowadzać następujące operacje: odczyt,
tworzenie, edycja, usuwanie. Pamiętaj, że w rzeczywistości
możesz każdemu zasobowi przypisać inne
operacje. Nie ma wymogu, aby wszystkim zasobom
odpowiadały jednakowe operacje.
Tworzymy role
Zanim utworzymy role, musimy stworzyć obiekt
klasy Zend_Acl:
require_once \'Zend/Acl.php\';
$objACL = new Zend_Acl();
To on jest podstawą listy uprawnień i on
dostarcza podstawowych metod, z których będziemy
korzystali. Tworzenie ról jest tworzeniem obiektów
klasy Zend_ACL_Role i dodawaniem ich do listy ACL:
require_once \'Zend/Acl/Role.php\';
$objACL->addRole(new Zend_Acl_Role(\'czytelnik\'))->addRole(new Zend_Acl_Role(\'redaktor\'))->addRole(new Zend_Acl_Role(\'administrator\'));
Jeśli powyższy zapis jest dla ciebie mało czytelny,
można go zapisać jako:
$objCzytelnik = new Zend_Acl_Role(\'czytelnik\');
$objRedaktor = new Zend_Acl_Role(\'redaktor\');
$objAdministrator = new Zend_Acl_Role(\'administrator\');
$objACL->addRole($objCzytelnik);
$objACL->addRole($objRedaktor);
$objACL->addRole($objAdministrator);
A więc tworzymy role, a następnie dodajemy je
do naszej listy ACL za pomocą metody {stala}addRole(){/stala}.
To jednak nie wszytko, co możemy zrobić. W Zend_ACL role mogą po sobie dziedziczyć:
$objACL->addRole($objRedaktor,\'czytelnik\');
W tej chwili rola \”redaktor\” dziedziczy po roli
\”czytelnik\”, dzięki czemu nie trzeba osobno dla niej
ustawiać uprawnień, które ma czytelnik. Ale o tym
za chwilkę.
Tworzymy zasoby
Zasoby tworzymy analogicznie do ról, z tą
różnicą, że klasą za nie odpowiedzialną jest Zend_
ACL_Resource, a dodawanie do listy ACL odbywa
się za pomocą metody {stala}add(){/stala}:
require_once \'Zend/Acl/Resource.php\';
$objACL->add(new Zend_Acl_Resource(\'news\'))->add(new Zend_Acl_Resource(\'artykuł\'));
lub:
$objNews = new Zend_Acl_Resource(\'news\');
$objArtykul = new Zend_Acl_Resource(\'artykuł\');
$objACL->add($objNews);
$objACL->add($objArtykul);
Także tutaj zasoby mogą dziedziczyć po innych
zasobach:
$objArtykulSponsorowany = new Zend_Acl_Resource(\'artykuł sponsorowany\', \'artykuł\');
Gdy mamy już zarówno role, jak i zasoby, możemy
przystąpić do nadawania im uprawnień.
Uprawnienia
Mamy już zasoby i role. Czas teraz nadać rolom
uprawnienia do zasobów. Do nadawania uprawnień
służy metoda {stala}allow(){/stala} klasy Zend_Acl:
$objACL->allow(\'czytelnik\', array(\'news\',\'artykuł\', \'artykuł sponsorowany\'),array(\'czytanie\'));
$objACL->allow(\'redaktor\', array(\'news\',\'artykuł\'), array(\'tworzenie\'));
A więc metoda {stala}allow(){/stala} przyjmuje następujące
parametry:
nazwa roli, której nadajemy uprawnienia. Może
to być nazwa w postaci napisu, obiekt klasy
Zend_ACL_Role, może też być to tablica nazw
lub obiektów, jeśli takie same uprawnienia
chcesz nadać kilku rolom jednocześnie,
nazwy, obiekty (klasy Zend_Acl_Resouce) lub
tablica nazw lub obiektów, wskazujących na
zasoby, do jakich chcesz nadać uprawnienia,
nazwy lub tablica nazw uprawnień do nadania.
Teraz można sprawdzić nadane uprawnienia:
echo $objACL->isAllowed(\'czytelnik\', \'news\', \'czytanie\') ? \'TAK\' : \'NIE\';
A więc umożliwiamy czytelnikowi czytanie
newsów. Powyższy kod zwróci napis TAK. A jeśli
zapytamy o możliwość tworzenia artykułów:
echo $objACL->isAllowed(\'czytelnik\', \'artykuł\', \'tworzenie\') ? \'TAK\' : \'NIE\';
Rola czytelnik nie ma uprawnienia tworzenie, przypisanego
do zasobu artykuł, a więc kod zwróci NIE.
To jednak nie wszytko, co możemy zrobić. Jeśli
nadaliśmy użytkownikowi pewne uprawnienie,
a chcielibyśmy je teraz odebrać, nie będzie z tym
żadnego problemu:
$objACL->deny(\'czytelnik\', \'news\',\'czytanie\');
Parametry metody {stala}deny(){/stala} są analogiczne do
tych metody {stala}allow(){/stala}. Od tej pory rola \”czytelnik\”
nie ma uprawnienia czytania newsów.
Nieco więcej o nadawaniu uprawnień
To, co już wiesz, pozwala na dość swobodne
posługiwanie się listą ACL. Jednak funkcje {stala}allow(){/stala}
i {stala}deny(){/stala} są bardzo elastyczne. Nie wszystkie parametry
są wymagane, nie wszystkie muszą być podawane
w postaci tablicy. Jeśli chcesz danej roli nadać wszystkie
prawa do zasobu, pomijasz w metodzie {stala}allow(){/stala}
ostatni parametr, określający rodzaj uprawnień:
$objACL->allow(\'administartor\', \'artykuł sponsorowany\');
Jeśli chcesz odebrać wszystkie uprawnienia
usuwania zasobu news wszystkim rolom, wystarczy
pierwszy parametr zastąpić wartością null:
$objACL->deny(null, \'news\', \'usuwanie\');
Utrwalanie drzewka ACL
Gdy już mamy nasze drzewko, trzeba je jakoś
zapisać. Możesz stworzyć w tym celu odpowiednią
strukturę w bazie i zapisywać tam uprawniania,
zaś wczytując je w pętli, wywoływać odpowiednio
metody {stala}allow(){/stala} i {stala}deny(){/stala}.
Jednak nie musisz się tak
męczyć. Wystarczy, że będziesz wiedział, jakie
masz role i zasoby, zaś drzewo uprawnień możesz
zapisać, serializując obiekt klasy Zend_ACL.
Zapis zserializowanego obiektu do bazy:
$strACL = serialize($objACL);
//zapisanie $strACL w bazie
Odczyt obiektu z bazy:
$objACL = unserialize($strACL); //strACL
odczytane wcześniej w bazy
Po takim odczytaniu ACL z bazy, można już korzystać
z obiektu klasy Zend_ACL, tak jak po jego uzupełnieniu
informacjami. I to wszystko! Prawda, że proste?