Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [ZendFramework] Zend_Acl, Jak odczytać uprawnienia w widoku?
nexis
post
Post #1





Grupa: Zarejestrowani
Postów: 1 012
Pomógł: 109
Dołączył: 26.09.2003
Skąd: nexis.pl

Ostrzeżenie: (0%)
-----


W jaki sposób mogę w widoku (np. views/scripts/index/index.phtml) uzyskać informację czy zalogowany użytkownik ma dostęp do jakiegoś działu? Chciałbym to uzyskać za pomocą funkcji typu isAllowed('controller', 'action') abym mógł ukryć linki w menu, do których użytkownik tak czy inaczej nie ma dostępu. Zend_Acl skonfigurowałem w następujący sposób:

bootstrap.php
  1. <?php
  2. defined('APPLICATION_PATH')
  3.   or define('APPLICATION_PATH', dirname(__FILE__));
  4.  
  5. defined('APPLICATION_ENVIRONMENT')
  6.    or define('APPLICATION_ENVIRONMENT', 'development');
  7.  
  8. $frontController = Zend_Controller_Front::getInstance();
  9. $frontController->setControllerDirectory(APPLICATION_PATH . '/controllers');
  10. $frontController->setParam('env', APPLICATION_ENVIRONMENT);
  11.  
  12. Zend_Layout::startMvc(APPLICATION_PATH . '/layouts/scripts');
  13. $view = Zend_Layout::getMvcInstance()->getView();
  14. $view->doctype('XHTML1_STRICT');
  15.  
  16. $configuration = new Zend_Config_Ini(APPLICATION_PATH . '/config/app.ini', APPLICATION_ENVIRONMENT);
  17.  
  18. $dbAdapter = Zend_Db::factory($configuration->database);
  19. $dbAdapter->query('SET NAMES utf8');
  20. Zend_Db_Table_Abstract::setDefaultAdapter($dbAdapter);
  21.  
  22. $registry = Zend_Registry::getInstance();
  23. $registry->configuration = $configuration;
  24. $registry->dbAdapter     = $dbAdapter;
  25.  
  26. require_once APPLICATION_PATH . '/models/Acl.php';
  27. require_once APPLICATION_PATH . '/models/Auth.php';
  28. $auth = Zend_Auth::getInstance();
  29. $acl  = new Acl($auth);
  30. $frontController->registerPlugin(new Auth($auth, $acl))
  31.                ->setParam('auth', $auth);
  32.  
  33.  
  34. unset($frontController, $view, $configuration, $dbAdapter, $registry);
  35. ?>


models/Auth.php
  1. <?php
  2. class Auth extends Zend_Controller_Plugin_Abstract
  3. {
  4.   public $_auth;
  5.   public $_acl;
  6.  
  7.   private $_noauth = array('module' => 'default', 'controller' => 'user', 'action' => 'login');
  8.   private $_noacl  = array('module' => 'default', 'controller' => 'user', 'action' => 'noAccess');
  9.  
  10.   public function __construct($auth, $acl)
  11.   {
  12.      $this->_auth = $auth;
  13.      $this->_acl  = $acl;
  14.   }
  15.   public function preDispatch(Zend_Controller_Request_Abstract $request)
  16.   {
  17.      $role = ($this->_auth->hasIdentity()) ? $this->_auth->getStorage()->read()->role : 'guest';
  18.  
  19.      $controller = $request->controller;
  20.      $action     = $request->action;
  21.      $module     = $request->module;
  22.      $resource   = $controller;
  23.  
  24.      if (!$this->_acl->has($resource)) {
  25.         $resource = null;
  26.      }
  27.  
  28.      if (!$this->_acl->isAllowed($role, $resource, $action)) {
  29.         if (!$this->_auth->hasIdentity()) {
  30.            $module     = $this->_noauth['module'];
  31.            $controller = $this->_noauth['controller'];
  32.            $action     = $this->_noauth['action'];
  33.         } else {
  34.            $module     = $this->_noacl['module'];
  35.            $controller = $this->_noacl['controller'];
  36.            $action     = $this->_noacl['action'];
  37.         }
  38.      }
  39.        
  40.      $request->setModuleName($module);
  41.      $request->setControllerName($controller);
  42.      $request->setActionName($action);
  43.   }
  44. }
  45. ?>


models/Acl.php
  1. <?php
  2. class Acl extends Zend_Acl
  3. {
  4.   public function __construct(Zend_Auth $auth)
  5.   {      
  6.      $this->add(new Zend_Acl_Resource('category'));
  7.      $this->add(new Zend_Acl_Resource('error'));
  8.      $this->add(new Zend_Acl_Resource('index'));
  9.      $this->add(new Zend_Acl_Resource('localization'));
  10.      $this->add(new Zend_Acl_Resource('object'));
  11.      $this->add(new Zend_Acl_Resource('objectcategory'));
  12.      $this->add(new Zend_Acl_Resource('objectelement'));
  13.      $this->add(new Zend_Acl_Resource('objectphoto'));
  14.      $this->add(new Zend_Acl_Resource('pattern'));
  15.      $this->add(new Zend_Acl_Resource('patternelement'));
  16.      $this->add(new Zend_Acl_Resource('postcode'));
  17.      $this->add(new Zend_Acl_Resource('user'));
  18.      
  19.      # Guest
  20.      $this->addRole(new Zend_Acl_Role('guest'));
  21.      $this->allow('guest', 'index');
  22.      $this->allow('guest', 'error');
  23.      $this->allow('guest', 'user');
  24.      
  25.      # Editor
  26.      $this->addRole(new Zend_Acl_Role('editor'), 'guest');
  27.      $this->allow('editor', 'localization');
  28.      $this->allow('editor', 'object');
  29.      $this->allow('editor', 'objectcategory');
  30.      $this->allow('editor', 'objectelement');
  31.      $this->allow('editor', 'objectphoto');
  32.      $this->allow('editor', 'postcode');
  33.      
  34.      # Manager
  35.      $this->addRole(new Zend_Acl_Role('manager'), 'editor');
  36.      $this->allow('manager', 'category');
  37.      $this->deny('manager', 'object', 'activate');
  38.      $this->allow('manager', 'pattern');
  39.      $this->allow('manager', 'patternelement');
  40.      
  41.      # Administrator
  42.      $this->addRole(new Zend_Acl_Role('administrator'));
  43.      $this->allow('administrator');
  44.   }
  45. }
  46. ?>


Ten post edytował nexis 15.01.2009, 23:06:41
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 15)
qba_rox
post
Post #2





Grupa: Zarejestrowani
Postów: 29
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


utworz sobie view helper, ktory renderuje ci menu i w nim pobierz z rejestru obiekt acl i sprawdzaj dostep do danego linku. chyba o to chodzi? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

jest pozno i tak sobie wymyslilem: (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
  1. <?php
  2. class Your_View_Helper_RenderMenu {
  3.  
  4.    public function RenderMenu() {
  5.        
  6.        $acl = Zend_Registry::get('acl');
  7.                $role = Your_Auth->getInstance()->getRole();
  8.  
  9.                if($acl->isAllowed($role, 'menu1', 'display')){
  10.                   $menu .= '<a>menu1</a>';
  11.                }
  12.    }
  13. //...
  14.  
  15. }
  16. ?>

o to chodzilo? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
batman
post
Post #3





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




A ja dodam od siebie, że ten helper powinien rozszerzać helper url i zwracać albo pusty ciąg (jeśli użytkownik nie ma uprawnień) lub to co zwraca helper url (jeśli użytkownik posiada uprawnienia).
Go to the top of the page
+Quote Post
LBO
post
Post #4





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(batman @ 16.01.2009, 09:42:51 ) *
A ja dodam od siebie, że ten helper powinien rozszerzać helper url i zwracać albo pusty ciąg (jeśli użytkownik nie ma uprawnień) lub to co zwraca helper url (jeśli użytkownik posiada uprawnienia).


Nie zgodzę sie z Tobą - to niepotrzebne mieszanie odpowiedzialności. Spójrz na poniższe podejście:

  1. <?php if($this->acl()->isAllowed($this->auth()->getRole(), 'menu1', 'display')) : ?>
  2. <div><?php print $this->menu(); ?></div>
  3. <?php else : ?>
  4. <div>menu niedostępne</div>
  5. <?php endif; ?>


Posiadasz większą kontrolę. Dodatkowo przy tym sposobie nie musisz się ograniczać do menu, ale także do pojedynczych linków tj. "edytuj", "usuń"; które prowadza do akcji wymagających pewnych uprawnień.

Ważne, żeby posiadać helpery wykonujące jak najbardziej "atomowy" kod. Dzięki temu możesz tworzyć i proste jak i bardzo skomplikowane struktury.
Go to the top of the page
+Quote Post
batman
post
Post #5





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Cytat(LBO @ 16.01.2009, 11:29:48 ) *
Nie zgodzę sie z Tobą - to niepotrzebne mieszanie odpowiedzialności. Spójrz na poniższe podejście:

Dlaczego?
Jeśli chcesz zrobić link, który ma się wyświetlać tylko dla konkretnej grupy użytkowników nie musisz kombinować z if-ami, które zaciemniają kod. Po prostu używasz helpera i nie martwisz się o to, czy dany element menu ma się pokazać, czy nie. A jeśli nie chcesz rozszerzać helpera url, to możesz po prostu go zastosować wewnątrz swojego helpera.
Go to the top of the page
+Quote Post
LBO
post
Post #6





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Przesadzasz z tymi ifami to właśnie bez Nich jest mniej czytelnie.

  1. <?php
  2. $this->menu();
  3. ?>


To mi nic nie mówi. Czy się będzie wyświetlać i kiedy.
Go to the top of the page
+Quote Post
batman
post
Post #7





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




To dodaj do przykładu jeszcze z 10 linków i każdy trzymaj w takim if-ie. Od razu można się pogubić. Poza tym wszystkie zmiany w uprawnieniach powodują, że trzeba w każdym if-ie zmieniać warunek. A tak, wystarczy zmienić to w jednym miejscu - w helperze.
Go to the top of the page
+Quote Post
LBO
post
Post #8





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Linki linkami. Natomiast taki sposób jaki ty podajesz powoduje, że przeładowujesz helper funkcjonalnością - menu() wyświetla menu i tyle. Ty chcesz jeszcze wpakować odpowiedzialność czy w ogóle ma je wyświetlać.

Nie twierdzę, że mam robić drzewko ifów tylko, że w budowie samych helperów trzeba zachować umiar. ot co.
Go to the top of the page
+Quote Post
batman
post
Post #9





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Nie do końca pisaliśmy o tym samym. Ty pisałeś o całym menu, a ja o konkretnych linkach. Dlatego nie możemy dojść do porozumienia. Jeśli autor stworzy helper, który wyświetli lub nie (w zależności od uprawnień) elementy menu (linki), wówczas osiągnie to o co mu chodziło.
Go to the top of the page
+Quote Post
LBO
post
Post #10





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Zawsze są jeszcze partiale. Nie wymagają dodatkowego helpera i posiadają korzyści płynące z mojego sposobu.
Go to the top of the page
+Quote Post
qba_rox
post
Post #11





Grupa: Zarejestrowani
Postów: 29
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Rozbijanie problemu wyswietlania linkow, na pojedyncze helpery nie ma zadnego sensu, bo jest to nie wydajne (zobacz ile obiektow musisz powolac i wykonywac wielokrotnie czynnosci ktore mozna zrobic raz) i robi bajzel w pliku widoku.
uwazam tak jak LBO, ze $this->renderMenu() jest duzo lepszym sposobem. Choc wcale nie zgodze sie z tym, ze sprawdzamy dostep tylko do calego menu.
Cytat
Poza tym wszystkie zmiany w uprawnieniach powodują, że trzeba w każdym if-ie zmieniać warunek. A tak, wystarczy zmienić to w jednym miejscu - w helperze.

nie prawda:
  1. <?php
  2. $menu['add'] = 'Dodaj';
  3. $menu['edit'] = 'Edytuj';
  4. $menu['delete'] = 'Usun';
  5.  
  6. //lub $menu = $model->getMenu();
  7. $menu = '';
  8. foreach($menu as $key=>$entry){
  9.  if($acl->isAllowed($role, "mainMenu:$key", 'display'))
  10.    $menu .= "<a>$entry</a>" . PHP_EOL;
  11.  
  12. }
  13.  
  14. return $menu;
  15. ?>

gdzie sa ify? bo ja ich nie widze (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) i mamy tylko jedna instrukcje sprawdzania uprawnien (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
batman
post
Post #12





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




No tak, ale cały czas kręcimy się w obrębie menu. A co jeśli trzeba stworzyć osobne linki, np edycja. Wówczas dla każdego linka trzeba będzie tworzyć helper. A o wydajność się nie martwię z dwóch powodów.
1. Jeśli stawiam aplikację na ZF, to jest to aplikacja kombajn, a nie wizytówka.
2. Wszystko co tylko można jest cache-owane.
Go to the top of the page
+Quote Post
qba_rox
post
Post #13





Grupa: Zarejestrowani
Postów: 29
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Hehe, mysle ze koles co zalozyl temat, ma juz odpowiedz (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)
masz racje, czasem warto poswiecic wydajnosc na rzecz lepszej swobody w programowaniu skoro i tak to cachujemy (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) uwazam ze twoje podejscie jest bardzo dobre jesli chodzi o o pojedyncze linki, ale uwazam ze moje jest lepsze jesli mowimy o zbiorze linkow luzno powiazanych z soba (np menu). Co szkodzi nam miec 2 helpery, do pojedynczow liknkow jak i do ich grupy? (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)
Go to the top of the page
+Quote Post
LBO
post
Post #14





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Nie narzekajcie z tymi obiektami helperów, bo te są tworzone tylko raz (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Przynajmniej byływ czasach ~1.0 (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Poprawcie mnie jeżeli się mylę, bo do ZF dawno nie zaglądałem.
Go to the top of the page
+Quote Post
batman
post
Post #15





Grupa: Moderatorzy
Postów: 2 921
Pomógł: 269
Dołączył: 11.08.2005
Skąd: 127.0.0.1




Dokładnie o to mi chodziło. Nie ma przecież obowiązku korzystać za każdym razem z helpera, który sprawdza prawa dostępu. Przecież nie każdy link prowadzi do strony z ograniczeniami.
Poza tym jeśli chodziłoby o menu, to też bym zrobił osobny helper do tego.


Zapomniałem dodać po pierwszego punktu w poprzednim moim poście, że taka aplikacja stoi na potężnej maszynie, której nie straszny jest ZF (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)


edit up
Tak. Obiekt helpera jest tworzony tylko raz.
Go to the top of the page
+Quote Post
qba_rox
post
Post #16





Grupa: Zarejestrowani
Postów: 29
Pomógł: 1
Dołączył: 12.01.2009
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


to prawda raz, ale nie chodzilo mi tu akurat o same obiekty helperow, tylko obiekty wewnatrz helpera, np obiekt modelu, konfiguracji (oczywiscie moze nie byc zadnych obiektow), poza tym odwolywanie sie dziesiatki razy do helpera nie jest wydajne, po to ludzie robia cos takiego.

Ten post edytował qba_rox 16.01.2009, 12:53:44
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 26.09.2025 - 01:37