Ik zit al tijden te goochelen met een ACL te maken die én dynamisch is, én zeer uitgebreid én een goede performance biedt. Een goed startpunt hiervoor leek me de blogpost van CodeUtopia. Hierin wordt eigenlijk het volgende gerealiseerd:
In de library met My_Acl_Factory lijkt me niet de juiste keuze, als je ook de blogpost van Ralph Schindler leest. De factory zal veelal business logic kennen.
Het verder verwerken van factory methods in de FCP lijkt me ook niet de juiste beslissing gezien je dan een hele dikke onhandelbare plugin krijgt. De factory in een model plaatsen lijkt me raar omdat het logica is, maar een aparte controller lijkt me niet kunnen: in de flow van het Zend Framework gebruik je de controllers als het weergegeven van content op je pagina (ze erven van Zend_Controller_Action). Zomaar ineens van het principe afwijken en een controller maken die géén Zend_Controller_Action is lijkt me ook niet de bedoeling.
Help!
- Een front controller plugin (FCP) die bij elke request de ACL initieert
- Op basis van Zend_Auth::getInstance()->hasIdentity() kijk je of je een user_role('guest') of user_role($auth_identity) moet aanmaken
- Op basis van de request params kijk je welke resource aangemaakt moet worden
- De user_role kent inheritance van group_role (die te nesten zijn)
- De page_resource kent inheritance van category_resource (ook weer te nesten)
- Slechts de permissies die binnen deze constraints voorkomen worden geladen uit de db en in de acl gestopt
- Wanneer role én resource én permission én mogelijke assertions goed staan krijg je toegang
PHP:
Deze fcp is dus onderdeel van mijn library. De modellen zitten in de applicatie laag (ook gemakkelijk om dan met Zend_Db_Table te werken e.d.). Ik zit alleen met de factory: wat is een goede plek om deze te plaatsen?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| class My_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract { public function dispatchLoopStartup (Zend_Controller_Request_Abstract $request) { if (!$this->_accessValid($request)) { throw new My_Acl_Exception('Access denied'); } } protected function _accessValid (Zend_Controller_Request_Abstract $request, $permission = 'view') { //Create resource $params = $request->getParams(); $resource = Model_Acl_Resource_Page($params); //Create role $auth = Zend_Auth::getInstance(); if ($auth->hasIdentity()) { $role = Model_Acl_Role_User($auth->getIdentity()); } else { $role = Model_Acl_Role_User(); //null will be interpretated as guest } $factory = new My_Acl_Factory(); $acl = $factory->createPageAcl($resource, $role); return $acl->hasRole($role) && $acl->has($resource) && $acl->isAllowed ($role, $resource, $permission); } } |
In de library met My_Acl_Factory lijkt me niet de juiste keuze, als je ook de blogpost van Ralph Schindler leest. De factory zal veelal business logic kennen.
Het verder verwerken van factory methods in de FCP lijkt me ook niet de juiste beslissing gezien je dan een hele dikke onhandelbare plugin krijgt. De factory in een model plaatsen lijkt me raar omdat het logica is, maar een aparte controller lijkt me niet kunnen: in de flow van het Zend Framework gebruik je de controllers als het weergegeven van content op je pagina (ze erven van Zend_Controller_Action). Zomaar ineens van het principe afwijken en een controller maken die géén Zend_Controller_Action is lijkt me ook niet de bedoeling.
Help!