Commit 19a31f8f45f319e828f9972cffb629ce2ae326bc
1 parent
c7e9e701
Exists in
master
and in
3 other branches
ajout de tests sur easyACL && nombreux bugfixes (merci les tests) !!!
Showing
3 changed files
with
91 additions
and
19 deletions
Show diff stats
src/Controller/AppController.php
... | ... | @@ -56,7 +56,8 @@ class AppController extends Controller { |
56 | 56 | private $CURRENT_ROLE = null; |
57 | 57 | |
58 | 58 | // EP 08/2017 |
59 | - protected $easyACL = array( | |
59 | + //protected $easyACL = array( | |
60 | + const easyACL = array( | |
60 | 61 | |
61 | 62 | /** Default ACL for ALL (logged) users |
62 | 63 | * |
... | ... | @@ -72,7 +73,10 @@ class AppController extends Controller { |
72 | 73 | // CRUD actions : |
73 | 74 | //'edit' => 'N', // update |
74 | 75 | //'delete' => 'N', |
75 | - 'autre' => 'Y', | |
76 | + 'autre1' => 'Y', | |
77 | + 'autre2' => 'N', | |
78 | + 'autre3' => 'Y', | |
79 | + 'autre4' => 'N', | |
76 | 80 | ), |
77 | 81 | |
78 | 82 | // Ajoute des ACL plus spécifiques (ci-dessus) pour le profil USER qui est plus restreint |
... | ... | @@ -119,6 +123,13 @@ class AppController extends Controller { |
119 | 123 | ), |
120 | 124 | ); // $easyACL |
121 | 125 | |
126 | + //if (isset($this->easyACL['DEFAULT'][$action])) { | |
127 | + public function hasACLRule($easyACL, $role, $action) { | |
128 | + //return isset($this->easyACL[$role][$action]); | |
129 | + //return (null !== self::easyACL[$role][$action]); | |
130 | + //return array_key_exists($role, self::easyACL) && array_key_exists($action, self::easyACL[$role]); | |
131 | + return array_key_exists($role, $easyACL) && array_key_exists($action, $easyACL[$role]); | |
132 | + } | |
122 | 133 | |
123 | 134 | //@todo |
124 | 135 | public function startsWith($haystack, $needle) { |
... | ... | @@ -142,9 +153,11 @@ class AppController extends Controller { |
142 | 153 | public function evalSpecificRule($condition, AppController $controller, $user, $role, $action, $id=null) { |
143 | 154 | // if starts with "&&" eval DEFAULT rule && specific rule |
144 | 155 | if ($this->startsWith($condition,'&&')) { |
145 | - if (! isset($controller->easyACL['DEFAULT'][$action])) return new \Exception('bad rule'); | |
156 | + //debug($condition); | |
157 | + //if (! isset($controller::easyACL['DEFAULT'][$action])) return new \Exception('bad rule'); | |
158 | + if (! array_key_exists($action, $controller::easyACL['DEFAULT']) ) return new \Exception('bad rule'); | |
146 | 159 | //return $this->evalACL($controller->easyACL['DEFAULT'][$action]) && $this->evalACL($condition); |
147 | - return $this->evalACL($controller->easyACL['DEFAULT'][$action]) . $this->evalACL($condition); | |
160 | + return $this->evalACL($controller::easyACL['DEFAULT'][$action]).' '.$this->evalACL($condition); | |
148 | 161 | } |
149 | 162 | // otherwise, eval only specific rule |
150 | 163 | return $this->evalACL($condition); |
... | ... | @@ -156,7 +169,11 @@ class AppController extends Controller { |
156 | 169 | * @param string $action |
157 | 170 | * @param string $id |
158 | 171 | */ |
159 | - public function isAuthorizedAction(AppController $controller, $user, $roleLong, $action, $id=null) { | |
172 | + //public function isAuthorizedAction(AppController $controller, $roleLong, $action, $id=null, $user=null) { | |
173 | + public function isAuthorizedAction($controller, $roleLong, $action, $id=null, $user=null) { | |
174 | + | |
175 | + $doDEBUG=true; | |
176 | + $doDEBUG=false; | |
160 | 177 | |
161 | 178 | switch ($roleLong) { |
162 | 179 | case 'Utilisateur': $role='USER'; break; |
... | ... | @@ -166,20 +183,38 @@ class AppController extends Controller { |
166 | 183 | case 'Super Administrateur': $role='SUPERADMIN'; break; |
167 | 184 | } |
168 | 185 | // 1) controller specific (role) rule for action |
169 | - if (isset($controller->easyACL[$role][$action])) | |
170 | - return $this->evalSpecificRule($controller->easyACL[$role][$action], $controller, $user, $role, $action); | |
186 | + //if (isset($controller->easyACL[$role][$action])) { | |
187 | + if (self::hasACLRule($controller::easyACL, $role, $action)) { | |
188 | + if ($doDEBUG) debug("CAS1"); | |
189 | + return $this->evalSpecificRule($controller::easyACL[$role][$action], $controller, $user, $role, $action); | |
190 | + } | |
171 | 191 | |
172 | 192 | // 2) AppController ($this) specific (role) rule for action |
173 | - if (isset($this->easyACL[$role][$action])) | |
174 | - return $this->evalSpecificRule($this->easyACL[$role][$action], $this, $user, $role, $action); | |
193 | + //if (isset($this->easyACL[$role][$action])) { | |
194 | + if (self::hasACLRule(self::easyACL, $role, $action)) { | |
195 | + if ($doDEBUG) debug("CAS2"); | |
196 | + return $this->evalSpecificRule(self::easyACL[$role][$action], $this, $user, $role, $action); | |
197 | + } | |
175 | 198 | |
176 | 199 | // 3) controller general (DEFAULT) rule for action |
177 | - if (isset($controller->easyACL['DEFAULT'][$action])) | |
178 | - return $this->evalACL($controller->easyACL['DEFAULT'][$action]); | |
200 | + //if (null !== $controller::easyACL['DEFAULT'][$action]) { | |
201 | + if (self::hasACLRule($controller::easyACL, 'DEFAULT', $action)) { | |
202 | + if ($doDEBUG) debug("CAS3"); | |
203 | + return $this->evalACL($controller::easyACL['DEFAULT'][$action]); | |
204 | + } | |
179 | 205 | |
206 | + // 4) AppController general (DEFAULT) rule for action | |
207 | + //if (isset($this->easyACL['DEFAULT'][$action])) { | |
208 | + //if (self::hasACLRule('DEFAULT',$action)) { | |
209 | + if (self::hasACLRule(self::easyACL, 'DEFAULT',$action)) { | |
210 | + if ($doDEBUG) debug("CAS4"); | |
211 | + return $this->evalACL(self::easyACL['DEFAULT'][$action]); | |
212 | + //return $this->evalACL(parent::getACLRule('DEFAULT',$action)); | |
213 | + } | |
214 | + | |
180 | 215 | /* |
181 | 216 | * (RECURSIVE CALL) |
182 | - * 4) controller previous specific (role) rule for action | |
217 | + * 5) controller previous specific (role) rule for action | |
183 | 218 | * ex: if role is 'SUPER', use 'ADMIN' rule |
184 | 219 | * ex: if role is 'ADMIN', use 'RESP' rule |
185 | 220 | * ex: if role is 'RESP', use 'USER' rule |
... | ... | @@ -187,8 +222,12 @@ class AppController extends Controller { |
187 | 222 | * Stop recursive call if role is 'USER' => no rule found, so default is authorize (Y) |
188 | 223 | */ |
189 | 224 | //if ($role == 'USER') return true; |
190 | - if ($role == 'USER') return 'Y'; | |
191 | - return $this->isAuthorizedAction($controller, $user, $this->getPreviousRole($role), $action, $id); | |
225 | + if ($role == 'USER') { | |
226 | + if ($doDEBUG) debug("CAS5"); | |
227 | + return 'Y'; | |
228 | + } | |
229 | + if ($doDEBUG) debug("CAS6"); | |
230 | + return $this->isAuthorizedAction($controller, $this->getPreviousRole($role), $action, $id, $user); | |
192 | 231 | |
193 | 232 | } |
194 | 233 | ... | ... |
src/Controller/MaterielsController.php
... | ... | @@ -39,8 +39,9 @@ class MaterielsController extends AppController { |
39 | 39 | ); |
40 | 40 | |
41 | 41 | // EP 08/2017 |
42 | - protected $easyACL = array( | |
43 | - | |
42 | + //protected $easyACL = array( | |
43 | + const easyACL = array( | |
44 | + | |
44 | 45 | /** Default ACL for ALL (logged) users |
45 | 46 | * |
46 | 47 | * Les actions non mentionnées sont accessibles à tous (par défaut), |
... | ... | @@ -59,13 +60,16 @@ class MaterielsController extends AppController { |
59 | 60 | //'find' => 'Y', // create |
60 | 61 | 'edit' => '(status == CREATED || status == VALIDATED)', // update |
61 | 62 | 'delete' => '(status == CREATED)', |
62 | - 'autre' => 'N', | |
63 | + 'autre1' => 'N', | |
64 | + 'autre2' => 'Y', | |
65 | + //'autre3' => 'N', | |
66 | + //'autre4' => 'NN', | |
63 | 67 | ), |
64 | 68 | |
65 | 69 | // Ajoute des ACL plus spécifiques (ci-dessus) pour le profil USER qui est plus restreint |
66 | 70 | // Les actions absentes ne sont pas surchargées (elles sont exécutées selon les conditions définies pour 'ALL') |
67 | 71 | 'USER' => array ( |
68 | - 'edit' => '&& (is_creator [[ is_user)', // is_owner = (nom_createur == CURRENT_USER_NAME) | |
72 | + 'edit' => '&& (is_creator || is_user)', // is_owner = (nom_createur == CURRENT_USER_NAME) | |
69 | 73 | // except fields status, owner, etiquette, and admin data, VALIDATED (only some fields, cf $modifiableFields in View/Materiels/scaffold.form.ctp) |
70 | 74 | 'delete' => '&& is_owner', |
71 | 75 | /* ceci n'a aucun sens car l'action sur le modèle "Pages" s'appelle toujours "display" (et non pas tools, infos, ou printers...) |
... | ... | @@ -186,7 +190,7 @@ class MaterielsController extends AppController { |
186 | 190 | * |
187 | 191 | * Tout le reste en dessous de cette ligne devient inutile !!! |
188 | 192 | */ |
189 | - $this->myDebug("isAuthorizedAction ? ".$this->isAuthorizedAction($this, $user, $role, $action, $id)); | |
193 | + $this->myDebug("isAuthorizedAction ? ".$this->isAuthorizedAction($this, $role, $action, $id, $user)); | |
190 | 194 | |
191 | 195 | /* |
192 | 196 | * Structure mise en place: | ... | ... |
tests/TestCase/Controller/MaterielsControllerTest.php
... | ... | @@ -7,6 +7,7 @@ use App\Controller\MaterielsController; |
7 | 7 | use Cake\ORM\TableRegistry; |
8 | 8 | //use phpDocumentor\Reflection\Types\Self_; |
9 | 9 | use Cake\Core\Configure; |
10 | +use App\Controller\AppController; | |
10 | 11 | |
11 | 12 | /** |
12 | 13 | * App\Controller\MaterielsController Test Case |
... | ... | @@ -127,6 +128,34 @@ class MaterielsControllerTest extends General { |
127 | 128 | * Chaque test d'une ACTION doit tester l'appel de cette action pour chaque ROLE |
128 | 129 | * |
129 | 130 | */ |
131 | + | |
132 | + /* | |
133 | + * ***************************************************************************** | |
134 | + * Basic ACL testing ($easyACL array rules) | |
135 | + * ***************************************************************************** | |
136 | + */ | |
137 | + public function testEasyACL() { | |
138 | + $role = 'USER_from_ldap'; | |
139 | + $this->authAs($role); | |
140 | + $roleLong = (new AppController())->getUserRole(); | |
141 | + $matCont = new MaterielsController(); | |
142 | + $this->_testEasyACL('N', $matCont, $roleLong, 'autre1'); | |
143 | + $this->_testEasyACL('Y', $matCont, $roleLong, 'autre2'); | |
144 | + $this->_testEasyACL('Y', $matCont, $roleLong, 'autre3'); | |
145 | + $this->_testEasyACL('N', $matCont, $roleLong, 'autre4'); | |
146 | + $this->_testEasyACL('Y', $matCont, $roleLong, 'unknown'); | |
147 | + $this->_testEasyACL('Y', $matCont, $roleLong, 'add'); | |
148 | + $this->_testEasyACL('(status == CREATED || status == VALIDATED) && (is_creator || is_user)', $matCont, $roleLong, 'edit'); | |
149 | + /* | |
150 | + $action='autre4'; | |
151 | + $rule = $matCont->isAuthorizedAction($matCont, $roleLong, $action); | |
152 | + $this->assertEquals('N', $rule, $roleLong.' do '.$action); | |
153 | + */ | |
154 | + } | |
155 | + private function _testEasyACL($expectedRule, AppController $controller, $roleLong, $action) { | |
156 | + $rule = $controller->isAuthorizedAction($controller, $roleLong, $action); | |
157 | + $this->assertEquals($expectedRule, $rule, $roleLong.' do '.$action); | |
158 | + } | |
130 | 159 | |
131 | 160 | |
132 | 161 | /* | ... | ... |