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

  • NIdentity
  • NPermission
  • NSimpleAuthenticator
  • NUser

Interfaces

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

Exceptions

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