Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Tokenizer
    • Utils
  • Tracy
    • Bridges
      • Nette
  • none

Classes

  • Identity
  • Passwords
  • Permission
  • SimpleAuthenticator
  • User

Interfaces

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

Exceptions

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