Packages

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • Identity
  • Permission
  • SimpleAuthenticator
  • User

Interfaces

  • IAuthenticator
  • IAuthorizator
  • IIdentity
  • IResource
  • IRole
  • IUserStorage

Exceptions

  • AuthenticationException
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  * @package Nette\Security
 11:  */
 12: 
 13: 
 14: 
 15: /**
 16:  * Access control list (ACL) functionality and privileges management.
 17:  *
 18:  * This solution is mostly based on Zend_Acl (c) Zend Technologies USA Inc. (http://www.zend.com), new BSD license
 19:  *
 20:  * @copyright  Copyright (c) 2005, 2007 Zend Technologies USA Inc.
 21:  * @author     David Grudl
 22:  *
 23:  * @property-read array $roles
 24:  * @property-read array $resources
 25:  * @property-read mixed $queriedRole
 26:  * @property-read mixed $queriedResource
 27:  * @package Nette\Security
 28:  */
 29: class Permission extends Object implements IAuthorizator
 30: {
 31:     /** @var array  Role storage */
 32:     private $roles = array();
 33: 
 34:     /** @var array  Resource storage */
 35:     private $resources = array();
 36: 
 37:     /** @var array  Access Control List rules; whitelist (deny everything to all) by default */
 38:     private $rules = array(
 39:         'allResources' => array(
 40:             'allRoles' => array(
 41:                 'allPrivileges' => array(
 42:                     'type' => self::DENY,
 43:                     'assert' => NULL,
 44:                 ),
 45:                 'byPrivilege' => array(),
 46:             ),
 47:             'byRole' => array(),
 48:         ),
 49:         'byResource' => array(),
 50:     );
 51: 
 52:     /** @var mixed */
 53:     private $queriedRole, $queriedResource;
 54: 
 55: 
 56:     /********************* roles ****************d*g**/
 57: 
 58: 
 59:     /**
 60:      * Adds a Role to the list. The most recently added parent
 61:      * takes precedence over parents that were previously added.
 62:      * @param  string
 63:      * @param  string|array
 64:      * @throws InvalidArgumentException
 65:      * @throws InvalidStateException
 66:      * @return self
 67:      */
 68:     public function addRole($role, $parents = NULL)
 69:     {
 70:         $this->checkRole($role, FALSE);
 71:         if (isset($this->roles[$role])) {
 72:             throw new InvalidStateException("Role '$role' already exists in the list.");
 73:         }
 74: 
 75:         $roleParents = array();
 76: 
 77:         if ($parents !== NULL) {
 78:             if (!is_array($parents)) {
 79:                 $parents = array($parents);
 80:             }
 81: 
 82:             foreach ($parents as $parent) {
 83:                 $this->checkRole($parent);
 84:                 $roleParents[$parent] = TRUE;
 85:                 $this->roles[$parent]['children'][$role] = TRUE;
 86:             }
 87:         }
 88: 
 89:         $this->roles[$role] = array(
 90:             'parents'  => $roleParents,
 91:             'children' => array(),
 92:         );
 93: 
 94:         return $this;
 95:     }
 96: 
 97: 
 98:     /**
 99:      * Returns TRUE if the Role exists in the list.
100:      * @param  string
101:      * @return bool
102:      */
103:     public function hasRole($role)
104:     {
105:         $this->checkRole($role, FALSE);
106:         return isset($this->roles[$role]);
107:     }
108: 
109: 
110:     /**
111:      * Checks whether Role is valid and exists in the list.
112:      * @param  string
113:      * @param  bool
114:      * @throws InvalidStateException
115:      * @return void
116:      */
117:     private function checkRole($role, $need = TRUE)
118:     {
119:         if (!is_string($role) || $role === '') {
120:             throw new InvalidArgumentException("Role must be a non-empty string.");
121: 
122:         } elseif ($need && !isset($this->roles[$role])) {
123:             throw new InvalidStateException("Role '$role' does not exist.");
124:         }
125:     }
126: 
127: 
128:     /**
129:      * Returns all Roles.
130:      * @return array
131:      */
132:     public function getRoles()
133:     {
134:         return array_keys($this->roles);
135:     }
136: 
137: 
138:     /**
139:      * Returns existing Role's parents ordered by ascending priority.
140:      * @param  string
141:      * @return array
142:      */
143:     public function getRoleParents($role)
144:     {
145:         $this->checkRole($role);
146:         return array_keys($this->roles[$role]['parents']);
147:     }
148: 
149: 
150:     /**
151:      * Returns TRUE if $role inherits from $inherit. If $onlyParents is TRUE,
152:      * then $role must inherit directly from $inherit.
153:      * @param  string
154:      * @param  string
155:      * @param  bool
156:      * @throws InvalidStateException
157:      * @return bool
158:      */
159:     public function roleInheritsFrom($role, $inherit, $onlyParents = FALSE)
160:     {
161:         $this->checkRole($role);
162:         $this->checkRole($inherit);
163: 
164:         $inherits = isset($this->roles[$role]['parents'][$inherit]);
165: 
166:         if ($inherits || $onlyParents) {
167:             return $inherits;
168:         }
169: 
170:         foreach ($this->roles[$role]['parents'] as $parent => $foo) {
171:             if ($this->roleInheritsFrom($parent, $inherit)) {
172:                 return TRUE;
173:             }
174:         }
175: 
176:         return FALSE;
177:     }
178: 
179: 
180:     /**
181:      * Removes the Role from the list.
182:      *
183:      * @param  string
184:      * @throws InvalidStateException
185:      * @return self
186:      */
187:     public function removeRole($role)
188:     {
189:         $this->checkRole($role);
190: 
191:         foreach ($this->roles[$role]['children'] as $child => $foo) {
192:             unset($this->roles[$child]['parents'][$role]);
193:         }
194: 
195:         foreach ($this->roles[$role]['parents'] as $parent => $foo) {
196:             unset($this->roles[$parent]['children'][$role]);
197:         }
198: 
199:         unset($this->roles[$role]);
200: 
201:         foreach ($this->rules['allResources']['byRole'] as $roleCurrent => $rules) {
202:             if ($role === $roleCurrent) {
203:                 unset($this->rules['allResources']['byRole'][$roleCurrent]);
204:             }
205:         }
206: 
207:         foreach ($this->rules['byResource'] as $resourceCurrent => $visitor) {
208:             if (isset($visitor['byRole'])) {
209:                 foreach ($visitor['byRole'] as $roleCurrent => $rules) {
210:                     if ($role === $roleCurrent) {
211:                         unset($this->rules['byResource'][$resourceCurrent]['byRole'][$roleCurrent]);
212:                     }
213:                 }
214:             }
215:         }
216: 
217:         return $this;
218:     }
219: 
220: 
221:     /**
222:      * Removes all Roles from the list.
223:      *
224:      * @return self
225:      */
226:     public function removeAllRoles()
227:     {
228:         $this->roles = array();
229: 
230:         foreach ($this->rules['allResources']['byRole'] as $roleCurrent => $rules) {
231:             unset($this->rules['allResources']['byRole'][$roleCurrent]);
232:         }
233: 
234:         foreach ($this->rules['byResource'] as $resourceCurrent => $visitor) {
235:             foreach ($visitor['byRole'] as $roleCurrent => $rules) {
236:                 unset($this->rules['byResource'][$resourceCurrent]['byRole'][$roleCurrent]);
237:             }
238:         }
239: 
240:         return $this;
241:     }
242: 
243: 
244:     /********************* resources ****************d*g**/
245: 
246: 
247:     /**
248:      * Adds a Resource having an identifier unique to the list.
249:      *
250:      * @param  string
251:      * @param  string
252:      * @throws InvalidArgumentException
253:      * @throws InvalidStateException
254:      * @return self
255:      */
256:     public function addResource($resource, $parent = NULL)
257:     {
258:         $this->checkResource($resource, FALSE);
259: 
260:         if (isset($this->resources[$resource])) {
261:             throw new InvalidStateException("Resource '$resource' already exists in the list.");
262:         }
263: 
264:         if ($parent !== NULL) {
265:             $this->checkResource($parent);
266:             $this->resources[$parent]['children'][$resource] = TRUE;
267:         }
268: 
269:         $this->resources[$resource] = array(
270:             'parent'   => $parent,
271:             'children' => array()
272:         );
273: 
274:         return $this;
275:     }
276: 
277: 
278:     /**
279:      * Returns TRUE if the Resource exists in the list.
280:      * @param  string
281:      * @return bool
282:      */
283:     public function hasResource($resource)
284:     {
285:         $this->checkResource($resource, FALSE);
286:         return isset($this->resources[$resource]);
287:     }
288: 
289: 
290:     /**
291:      * Checks whether Resource is valid and exists in the list.
292:      * @param  string
293:      * @param  bool
294:      * @throws InvalidStateException
295:      * @return void
296:      */
297:     private function checkResource($resource, $need = TRUE)
298:     {
299:         if (!is_string($resource) || $resource === '') {
300:             throw new InvalidArgumentException("Resource must be a non-empty string.");
301: 
302:         } elseif ($need && !isset($this->resources[$resource])) {
303:             throw new InvalidStateException("Resource '$resource' does not exist.");
304:         }
305:     }
306: 
307: 
308:     /**
309:      * Returns all Resources.
310:      * @return array
311:      */
312:     public function getResources()
313:     {
314:         return array_keys($this->resources);
315:     }
316: 
317: 
318:     /**
319:      * Returns TRUE if $resource inherits from $inherit. If $onlyParents is TRUE,
320:      * then $resource must inherit directly from $inherit.
321:      *
322:      * @param  string
323:      * @param  string
324:      * @param  bool
325:      * @throws InvalidStateException
326:      * @return bool
327:      */
328:     public function resourceInheritsFrom($resource, $inherit, $onlyParent = FALSE)
329:     {
330:         $this->checkResource($resource);
331:         $this->checkResource($inherit);
332: 
333:         if ($this->resources[$resource]['parent'] === NULL) {
334:             return FALSE;
335:         }
336: 
337:         $parent = $this->resources[$resource]['parent'];
338:         if ($inherit === $parent) {
339:             return TRUE;
340: 
341:         } elseif ($onlyParent) {
342:             return FALSE;
343:         }
344: 
345:         while ($this->resources[$parent]['parent'] !== NULL) {
346:             $parent = $this->resources[$parent]['parent'];
347:             if ($inherit === $parent) {
348:                 return TRUE;
349:             }
350:         }
351: 
352:         return FALSE;
353:     }
354: 
355: 
356:     /**
357:      * Removes a Resource and all of its children.
358:      *
359:      * @param  string
360:      * @throws InvalidStateException
361:      * @return self
362:      */
363:     public function removeResource($resource)
364:     {
365:         $this->checkResource($resource);
366: 
367:         $parent = $this->resources[$resource]['parent'];
368:         if ($parent !== NULL) {
369:             unset($this->resources[$parent]['children'][$resource]);
370:         }
371: 
372:         $removed = array($resource);
373:         foreach ($this->resources[$resource]['children'] as $child => $foo) {
374:             $this->removeResource($child);
375:             $removed[] = $child;
376:         }
377: 
378:         foreach ($removed as $resourceRemoved) {
379:             foreach ($this->rules['byResource'] as $resourceCurrent => $rules) {
380:                 if ($resourceRemoved === $resourceCurrent) {
381:                     unset($this->rules['byResource'][$resourceCurrent]);
382:                 }
383:             }
384:         }
385: 
386:         unset($this->resources[$resource]);
387:         return $this;
388:     }
389: 
390: 
391:     /**
392:      * Removes all Resources.
393:      * @return self
394:      */
395:     public function removeAllResources()
396:     {
397:         foreach ($this->resources as $resource => $foo) {
398:             foreach ($this->rules['byResource'] as $resourceCurrent => $rules) {
399:                 if ($resource === $resourceCurrent) {
400:                     unset($this->rules['byResource'][$resourceCurrent]);
401:                 }
402:             }
403:         }
404: 
405:         $this->resources = array();
406:         return $this;
407:     }
408: 
409: 
410:     /********************* defining rules ****************d*g**/
411: 
412: 
413:     /**
414:      * Allows one or more Roles access to [certain $privileges upon] the specified Resource(s).
415:      * If $assertion is provided, then it must return TRUE in order for rule to apply.
416:      *
417:      * @param  string|array|Permission::ALL  roles
418:      * @param  string|array|Permission::ALL  resources
419:      * @param  string|array|Permission::ALL  privileges
420:      * @param  callable    assertion
421:      * @return self
422:      */
423:     public function allow($roles = self::ALL, $resources = self::ALL, $privileges = self::ALL, $assertion = NULL)
424:     {
425:         $this->setRule(TRUE, self::ALLOW, $roles, $resources, $privileges, $assertion);
426:         return $this;
427:     }
428: 
429: 
430:     /**
431:      * Denies one or more Roles access to [certain $privileges upon] the specified Resource(s).
432:      * If $assertion is provided, then it must return TRUE in order for rule to apply.
433:      *
434:      * @param  string|array|Permission::ALL  roles
435:      * @param  string|array|Permission::ALL  resources
436:      * @param  string|array|Permission::ALL  privileges
437:      * @param  callable    assertion
438:      * @return self
439:      */
440:     public function deny($roles = self::ALL, $resources = self::ALL, $privileges = self::ALL, $assertion = NULL)
441:     {
442:         $this->setRule(TRUE, self::DENY, $roles, $resources, $privileges, $assertion);
443:         return $this;
444:     }
445: 
446: 
447:     /**
448:      * Removes "allow" permissions from the list in the context of the given Roles, Resources, and privileges.
449:      *
450:      * @param  string|array|Permission::ALL  roles
451:      * @param  string|array|Permission::ALL  resources
452:      * @param  string|array|Permission::ALL  privileges
453:      * @return self
454:      */
455:     public function removeAllow($roles = self::ALL, $resources = self::ALL, $privileges = self::ALL)
456:     {
457:         $this->setRule(FALSE, self::ALLOW, $roles, $resources, $privileges);
458:         return $this;
459:     }
460: 
461: 
462:     /**
463:      * Removes "deny" restrictions from the list in the context of the given Roles, Resources, and privileges.
464:      *
465:      * @param  string|array|Permission::ALL  roles
466:      * @param  string|array|Permission::ALL  resources
467:      * @param  string|array|Permission::ALL  privileges
468:      * @return self
469:      */
470:     public function removeDeny($roles = self::ALL, $resources = self::ALL, $privileges = self::ALL)
471:     {
472:         $this->setRule(FALSE, self::DENY, $roles, $resources, $privileges);
473:         return $this;
474:     }
475: 
476: 
477:     /**
478:      * Performs operations on Access Control List rules.
479:      * @param  bool  operation add?
480:      * @param  bool  type
481:      * @param  string|array|Permission::ALL  roles
482:      * @param  string|array|Permission::ALL  resources
483:      * @param  string|array|Permission::ALL  privileges
484:      * @param  callable    assertion
485:      * @throws InvalidStateException
486:      * @return self
487:      */
488:     protected function setRule($toAdd, $type, $roles, $resources, $privileges, $assertion = NULL)
489:     {
490:         // ensure that all specified Roles exist; normalize input to array of Roles or NULL
491:         if ($roles === self::ALL) {
492:             $roles = array(self::ALL);
493: 
494:         } else {
495:             if (!is_array($roles)) {
496:                 $roles = array($roles);
497:             }
498: 
499:             foreach ($roles as $role) {
500:                 $this->checkRole($role);
501:             }
502:         }
503: 
504:         // ensure that all specified Resources exist; normalize input to array of Resources or NULL
505:         if ($resources === self::ALL) {
506:             $resources = array(self::ALL);
507: 
508:         } else {
509:             if (!is_array($resources)) {
510:                 $resources = array($resources);
511:             }
512: 
513:             foreach ($resources as $resource) {
514:                 $this->checkResource($resource);
515:             }
516:         }
517: 
518:         // normalize privileges to array
519:         if ($privileges === self::ALL) {
520:             $privileges = array();
521: 
522:         } elseif (!is_array($privileges)) {
523:             $privileges = array($privileges);
524:         }
525: 
526:         $assertion = $assertion ? new Callback($assertion) : NULL;
527: 
528:         if ($toAdd) { // add to the rules
529:             foreach ($resources as $resource) {
530:                 foreach ($roles as $role) {
531:                     $rules = & $this->getRules($resource, $role, TRUE);
532:                     if (count($privileges) === 0) {
533:                         $rules['allPrivileges']['type'] = $type;
534:                         $rules['allPrivileges']['assert'] = $assertion;
535:                         if (!isset($rules['byPrivilege'])) {
536:                             $rules['byPrivilege'] = array();
537:                         }
538:                     } else {
539:                         foreach ($privileges as $privilege) {
540:                             $rules['byPrivilege'][$privilege]['type'] = $type;
541:                             $rules['byPrivilege'][$privilege]['assert'] = $assertion;
542:                         }
543:                     }
544:                 }
545:             }
546: 
547:         } else { // remove from the rules
548:             foreach ($resources as $resource) {
549:                 foreach ($roles as $role) {
550:                     $rules = & $this->getRules($resource, $role);
551:                     if ($rules === NULL) {
552:                         continue;
553:                     }
554:                     if (count($privileges) === 0) {
555:                         if ($resource === self::ALL && $role === self::ALL) {
556:                             if ($type === $rules['allPrivileges']['type']) {
557:                                 $rules = array(
558:                                     'allPrivileges' => array(
559:                                         'type' => self::DENY,
560:                                         'assert' => NULL
561:                                         ),
562:                                     'byPrivilege' => array()
563:                                     );
564:                             }
565:                             continue;
566:                         }
567:                         if ($type === $rules['allPrivileges']['type']) {
568:                             unset($rules['allPrivileges']);
569:                         }
570:                     } else {
571:                         foreach ($privileges as $privilege) {
572:                             if (isset($rules['byPrivilege'][$privilege]) &&
573:                                 $type === $rules['byPrivilege'][$privilege]['type']) {
574:                                 unset($rules['byPrivilege'][$privilege]);
575:                             }
576:                         }
577:                     }
578:                 }
579:             }
580:         }
581:         return $this;
582:     }
583: 
584: 
585:     /********************* querying the ACL ****************d*g**/
586: 
587: 
588:     /**
589:      * Returns TRUE if and only if the Role has access to [certain $privileges upon] the Resource.
590:      *
591:      * This method checks Role inheritance using a depth-first traversal of the Role list.
592:      * The highest priority parent (i.e., the parent most recently added) is checked first,
593:      * and its respective parents are checked similarly before the lower-priority parents of
594:      * the Role are checked.
595:      *
596:      * @param  string|Permission::ALL|IRole  role
597:      * @param  string|Permission::ALL|IResource  resource
598:      * @param  string|Permission::ALL  privilege
599:      * @throws InvalidStateException
600:      * @return bool
601:      */
602:     public function isAllowed($role = self::ALL, $resource = self::ALL, $privilege = self::ALL)
603:     {
604:         $this->queriedRole = $role;
605:         if ($role !== self::ALL) {
606:             if ($role instanceof IRole) {
607:                 $role = $role->getRoleId();
608:             }
609:             $this->checkRole($role);
610:         }
611: 
612:         $this->queriedResource = $resource;
613:         if ($resource !== self::ALL) {
614:             if ($resource instanceof IResource) {
615:                 $resource = $resource->getResourceId();
616:             }
617:             $this->checkResource($resource);
618:         }
619: 
620:         do {
621:             // depth-first search on $role if it is not 'allRoles' pseudo-parent
622:             if ($role !== NULL && NULL !== ($result = $this->searchRolePrivileges($privilege === self::ALL, $role, $resource, $privilege))) {
623:                 break;
624:             }
625: 
626:             if ($privilege === self::ALL) {
627:                 if ($rules = $this->getRules($resource, self::ALL)) { // look for rule on 'allRoles' psuedo-parent
628:                     foreach ($rules['byPrivilege'] as $privilege => $rule) {
629:                         if (self::DENY === ($result = $this->getRuleType($resource, NULL, $privilege))) {
630:                             break 2;
631:                         }
632:                     }
633:                     if (NULL !== ($result = $this->getRuleType($resource, NULL, NULL))) {
634:                         break;
635:                     }
636:                 }
637:             } else {
638:                 if (NULL !== ($result = $this->getRuleType($resource, NULL, $privilege))) { // look for rule on 'allRoles' pseudo-parent
639:                     break;
640: 
641:                 } elseif (NULL !== ($result = $this->getRuleType($resource, NULL, NULL))) {
642:                     break;
643:                 }
644:             }
645: 
646:             $resource = $this->resources[$resource]['parent']; // try next Resource
647:         } while (TRUE);
648: 
649:         $this->queriedRole = $this->queriedResource = NULL;
650:         return $result;
651:     }
652: 
653: 
654:     /**
655:      * Returns real currently queried Role. Use by assertion.
656:      * @return mixed
657:      */
658:     public function getQueriedRole()
659:     {
660:         return $this->queriedRole;
661:     }
662: 
663: 
664:     /**
665:      * Returns real currently queried Resource. Use by assertion.
666:      * @return mixed
667:      */
668:     public function getQueriedResource()
669:     {
670:         return $this->queriedResource;
671:     }
672: 
673: 
674:     /********************* internals ****************d*g**/
675: 
676: 
677:     /**
678:      * Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule
679:      * allowing/denying $role access to a/all $privilege upon $resource.
680:      * @param  bool  all (true) or one?
681:      * @param  string
682:      * @param  string
683:      * @param  string  only for one
684:      * @return mixed  NULL if no applicable rule is found, otherwise returns ALLOW or DENY
685:      */
686:     private function searchRolePrivileges($all, $role, $resource, $privilege)
687:     {
688:         $dfs = array(
689:             'visited' => array(),
690:             'stack' => array($role),
691:         );
692: 
693:         while (NULL !== ($role = array_pop($dfs['stack']))) {
694:             if (isset($dfs['visited'][$role])) {
695:                 continue;
696:             }
697:             if ($all) {
698:                 if ($rules = $this->getRules($resource, $role)) {
699:                     foreach ($rules['byPrivilege'] as $privilege2 => $rule) {
700:                         if (self::DENY === $this->getRuleType($resource, $role, $privilege2)) {
701:                             return self::DENY;
702:                         }
703:                     }
704:                     if (NULL !== ($type = $this->getRuleType($resource, $role, NULL))) {
705:                         return $type;
706:                     }
707:                 }
708:             } else {
709:                 if (NULL !== ($type = $this->getRuleType($resource, $role, $privilege))) {
710:                     return $type;
711: 
712:                 } elseif (NULL !== ($type = $this->getRuleType($resource, $role, NULL))) {
713:                     return $type;
714:                 }
715:             }
716: 
717:             $dfs['visited'][$role] = TRUE;
718:             foreach ($this->roles[$role]['parents'] as $roleParent => $foo) {
719:                 $dfs['stack'][] = $roleParent;
720:             }
721:         }
722:         return NULL;
723:     }
724: 
725: 
726:     /**
727:      * Returns the rule type associated with the specified Resource, Role, and privilege.
728:      * @param  string|Permission::ALL
729:      * @param  string|Permission::ALL
730:      * @param  string|Permission::ALL
731:      * @return mixed  NULL if a rule does not exist or assertion fails, otherwise returns ALLOW or DENY
732:      */
733:     private function getRuleType($resource, $role, $privilege)
734:     {
735:         if (!$rules = $this->getRules($resource, $role)) {
736:             return NULL;
737:         }
738: 
739:         if ($privilege === self::ALL) {
740:             if (isset($rules['allPrivileges'])) {
741:                 $rule = $rules['allPrivileges'];
742:             } else {
743:                 return NULL;
744:             }
745:         } elseif (!isset($rules['byPrivilege'][$privilege])) {
746:             return NULL;
747: 
748:         } else {
749:             $rule = $rules['byPrivilege'][$privilege];
750:         }
751: 
752:         if ($rule['assert'] === NULL || $rule['assert']->__invoke($this, $role, $resource, $privilege)) {
753:             return $rule['type'];
754: 
755:         } elseif ($resource !== self::ALL || $role !== self::ALL || $privilege !== self::ALL) {
756:             return NULL;
757: 
758:         } elseif (self::ALLOW === $rule['type']) {
759:             return self::DENY;
760: 
761:         } else {
762:             return self::ALLOW;
763:         }
764:     }
765: 
766: 
767:     /**
768:      * Returns the rules associated with a Resource and a Role, or NULL if no such rules exist.
769:      * If the $create parameter is TRUE, then a rule set is first created and then returned to the caller.
770:      * @param  string|Permission::ALL
771:      * @param  string|Permission::ALL
772:      * @param  bool
773:      * @return array|NULL
774:      */
775:     private function & getRules($resource, $role, $create = FALSE)
776:     {
777:         $null = NULL;
778:         if ($resource === self::ALL) {
779:             $visitor = & $this->rules['allResources'];
780:         } else {
781:             if (!isset($this->rules['byResource'][$resource])) {
782:                 if (!$create) {
783:                     return $null;
784:                 }
785:                 $this->rules['byResource'][$resource] = array();
786:             }
787:             $visitor = & $this->rules['byResource'][$resource];
788:         }
789: 
790:         if ($role === self::ALL) {
791:             if (!isset($visitor['allRoles'])) {
792:                 if (!$create) {
793:                     return $null;
794:                 }
795:                 $visitor['allRoles']['byPrivilege'] = array();
796:             }
797:             return $visitor['allRoles'];
798:         }
799: 
800:         if (!isset($visitor['byRole'][$role])) {
801:             if (!$create) {
802:                 return $null;
803:             }
804:             $visitor['byRole'][$role]['byPrivilege'] = array();
805:         }
806: 
807:         return $visitor['byRole'][$role];
808:     }
809: 
810: }
811: 
Nette Framework 2.0.12 (for PHP 5.2, un-prefixed) API API documentation generated by ApiGen 2.8.0