Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ZendFramework] ACL i moduły
Forum PHP.pl > Forum > PHP > Frameworki
Thuunder
Witam,

mam do zrobienia aplikację. Aplikacja ma być dostępna tylko po zalogowaniu, podzieliłem na moduły ale zastanawiam się nad paroma rzeczami:
Czy jeśli mam mam 2 moduły "biznesowe", to jak rozwiązać sprawę z uprawnieniami. Stworzyć dodatkowy moduł default i w nim acl czy do każdego modułu osobno ?

Pytanie też odnośnie Zendowego ACL'a. Jak mają być wyświetlane produkty, które dany user może zobaczyć. W bazie jest tabela z userem i produktami, które może zobaczyć.
Pytanie tylko jak to połączyć z ACL'em żeby wyświetlały mu się tylko te produkty, które są do niego przypisane ? Nie bardzo wiem jak wykorzystać do tego acl ? Jakiś helper ?
Jakieś sugestie ?
Spawnm
Powiedz jak zaimplementowałeś acl dla usera.
Możliwe że wystarczy coś w stylu:
id, produkt_id, role_id
A potem select z joinem.
Thuunder
nic na razie nie implementowałem. Przymierzam się właśnie do tego, ale nie bardzo wiem jak to zrobić.
KrzysiekWildfire
Ja używam Acl razem z Zend_Navigation (pięknie się łączą). W produkcie możesz dodać jaki poziom uprawnień musi mieć użytkownik aby zobaczyć produkt. Więc, jeżeli produkt ma np. allow_for = 'privilege_a', to jest dostępny tylko dla użytkowników którzy mają uprawnienie 'privilege_a' lub dziedziczą z tego uprawnienia. Jeżeli masz grupę produktów, to proponuję Ci zostosować identyfikatory numeryczne, powiedzmy:
developer = 1
admin = 2
business = 3
standard = 4
demo = 5
guest = 6
i wtedy przy zapytaniach o produkty będziesz mógł zrobić tak:
  1. ...->where('allow_for >= ?',$user->role_id);

Sposobów na zrobienie tego jest sporo.
Skyline
Mozesz utworzyc user'a ktory ma dostep do danego modulu, a w danym module do kontrolera i/lub akcji.
Userzy moga dziedziczyc po sobie uprawnienia.
darko
Można wydzielić w ACL Zenda uprawnienia per moduł. W manualu dalsze info.
Thuunder
W bazie mam id usera oraz id produktu (stanowią parę). User może widzieć jeden lub więcej produktów. I chodzi mi o to w jaki sposób wyświetlić na liście rozwijalnej listę produktów dla danego użytkownika. Wydaje mi się, że KrzysiekWildfire jest najbliżej tego o co mi chodzi. Dla różnych modułów są różne połączenia usera z produktem, są niezależne. Ale oczywiście lista userów jest ta sama dla całej aplikacji.
Oraz jeśli mam dwa moduły docelowe to jak zorganizować logowanie (bez dostępu dla gościa), robić moduł default w którym byłby kontroler np. konto i w nim logowanie ? Robić jakiś plugin do tego acl'a czy jakiś kontroler po którym dziedziczyłyby inne kontrolery z modułów?
Na razie chodzę po tym zendzie trochę po omacku :], tak więc z góry dzięki za info.
darko
Daaaawno nie pisałem w ZF, ale z tego, co pamiętam, to w swoich projektach używałem napisanego własnoręcznie pluginu, który za każdym razem sprawdzał czy określona rola posiada dostęp do żądanej akcji (zasobu) według reguł zdefiniowanych w ACL. Odnośnie pytania o przefiltrowanie listy produktów należących do konkretnego usera, to myślę, że nie ma większego sensu zaprzęgać w tym obszarze ACLa, wystarczy wyciągnąć odpowiednio dane z bazy po id użytkownika.
KrzysiekWildfire
To będzie tak:

To przykładowy plik ini w którym trzymam prosty układ przywilejów:

acl.resources[] = "admin"
acl.resources[] = "developer"
acl.resources[] = "config"
acl.resources[] = "premium"
acl.resources[] = "nonpremium"
acl.resources[] = "guest"

acl.roles[] = "admin"
acl.roles[] = "developer"
acl.roles[] = "moderator"
acl.roles[] = "premium"
acl.roles[] = "nonpremium"
acl.roles[] = "guest"

acl.privilages.admin[] = "admin"
acl.privilages.admin[] = "config"
acl.privilages.admin[] = "guest"
acl.privilages.admin[] = "premium"
acl.privilages.admin[] = "nonpremium"

acl.privilages.moderator[] = "admin"
acl.privilages.moderator[] = "guest"

acl.privilages.developer[] = "admin"
acl.privilages.developer[] = "developer"
acl.privilages.developer[] = "config"
acl.privilages.developer[] = "premium"
acl.privilages.developer[] = "nonpremium"
acl.privilages.developer[] = "guest"

acl.privilages.premium[] = "premium"
acl.privilages.premium[] = "nonpremium"
acl.privilages.premium[] = "guest"

acl.privilages.nonpremium[] = "nonpremium"
acl.privilages.nonpremium[] = "guest"

acl.privilages.guest[] = "guest"

Tu muszę zaznaczyć (osoby które korzystają codziennie to widzą), że nie wykorzystałem dziedziczenia, aby ładnie to zobrazować.
Pierwsza część ("Resources") - zawiera informacje jakie grupy dostępu mamy. Druga część ("roles") zawiera informacje, jakie mamy grupy użytkowników. Tutaj jako resources mógłbym użyć grupy produktów. Pozostałe bloki przydzielają możliwość przeglądania danej grupy dostępów przez daną grupę użytkowników. Oczywiście samo wsadzenie tego do konfiguracji nic nie da - trzeba stworzyć plugin który pobierze tą konfiguruje i wsadzi wszystko w klasę Zend_Acl. To tego trzymam nawigację w Zend_Navigation (MVC) gdzie trzymam informację kto ma dostęp do danej strony.

Plugin wygląda tak:
  1. class MyScripts_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract {
  2.  
  3. public function preDispatch(Zend_Controller_Request_Abstract $request) {
  4. $acl = new Zend_Acl();
  5. $aclOptions = new Zend_Config_Ini(APPLICATION_PATH.'/configs/acl.ini','production'); //pobranie powyższej konfiguracji
  6. $aclOptions = $aclOptions->toArray();
  7. $aclOptions = $aclOptions['acl'];
  8.  
  9. foreach ($aclOptions['roles'] as $role){
  10. $acl->addRole(new Zend_Acl_Role($role));
  11. }
  12.  
  13. foreach ($aclOptions['resources'] as $resource){
  14. $acl->addResource(new Zend_Acl_Resource($resource));
  15. }
  16. foreach ($aclOptions['privilages'] as $role=>$resource){
  17. foreach ($resource as $res){
  18. if (count(explode('_',$res))>1){
  19. $acl->allow($role,current(explode('_',$res)),end(explode('_',$res)));
  20. }else{
  21. $acl->allow($role,$res);
  22. }
  23. }
  24. }
  25.  
  26. //do tego momentu pobrano konfigurację w umieszczono ją w Zend_Acl
  27.  
  28. Zend_Registry::set('Zend_Acl', $acl);
  29. $navigationConfig = new Zend_Config_Xml(APPLICATION_PATH.'/configs/navigation.xml','navpage'); //pobranie nawigacji (Zend_Navigation)
  30. $navigation = new Zend_Navigation($navigationConfig->toArray());
  31. Zend_Registry::set('Zend_Navigation',$navigation);
  32. Zend_View_Helper_Navigation::setDefaultAcl($acl); //Tutaj nawigacji przekazuje acl'a, tak aby nawigacja wyświetlała tylko te strony, do których użytkownik ma dostęp (czego oczy nie widzą, tego sercu nie żal)
  33. if (Zend_Auth::getInstance()->hasIdentity()){ //jeżeli user jest zalogowany
  34. Zend_View_Helper_Navigation::setDefaultRole(Zend_Auth::getInstance()->getIdentity()->role);
  35. }else{
  36. Zend_View_Helper_Navigation::setDefaultRole('guest');
  37. }
  38. // !!!
  39. // $pagepriv = $navigation->findOneBy('active', 1); //Tak można wyciągnąć stronę na której aktualnie się znajdujemy (dodaje, bo wiele osób ma z tym problem)
  40. // !!!
  41. if (Zend_Auth::getInstance()->hasIdentity()){
  42. $role = Zend_Auth::getInstance()->getIdentity()->role;
  43. }else{
  44. $role = 'guest';
  45. }
  46. if (!$acl->isAllowed($role,$pagepriv)){ //sprawdzamy, czy użytkownik może tutaj przebywać, jeżeli nie, to wyświetlamy mu stronę z brakiem uprawnień
  47. $request->setModuleName('default');
  48. $request->setControllerName('Error');
  49. $request->setActionName('denied');
  50. }
  51. }
  52. }

Jeszcze kilka rzeczy wymaga naprawienia, więc jak ktoś coś poprawi w klasie, to niech da znać smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.