Source for file Permission.php
Documentation is available at Permission.php
- 1: <?php
- 3: /**
- 4: * Nette Framework
- 5: *
- 6: * Copyright (c) 2004, 2009 David Grudl (http://davidgrudl.com)
- 7: *
- 8: * This source file is subject to the "Nette license" that is bundled
- 9: * with this package in the file license.txt.
- 10: *
- 11: * For more information please see http://nettephp.com
- 12: *
- 18: */
- 28: /**
- 29: * Access control list (ACL) functionality and privileges management.
- 30: *
- 31: * This solution is mostly based on Zend_Acl (c) Zend Technologies USA Inc. (http://www.zend.com), new BSD license
- 32: *
- 37: */
- 39: {
- 66: /********************* roles ****************d*g**/
- 69: /**
- 70: * Adds a Role to the list.
- 71: *
- 72: * The $parents parameter may be a Role identifier (or array of identifiers)
- 73: * to indicate the Roles from which the newly added Role will directly inherit.
- 74: *
- 75: * In order to resolve potential ambiguities with conflicting rules inherited
- 76: * from different parents, the most recently added parent takes precedence over
- 77: * parents that were previously added. In other words, the first parent added
- 78: * will have the least priority, and the last parent added will have the
- 79: * highest priority.
- 80: *
- 86: */
- 88: {
- 93: }
- 100: }
- 106: }
- 107: }
- 115: }
- 119: /**
- 120: * Returns TRUE if the Role exists in the list.
- 123: */
- 125: {
- 128: }
- 132: /**
- 133: * Checks whether Role is valid and exists in the list.
- 138: */
- 140: {
- 146: }
- 147: }
- 151: /**
- 152: * Returns an array of an existing Role's parents.
- 153: *
- 154: * The parent Roles are ordered in this array by ascending priority.
- 155: * The highest priority parent Role, last in the array, corresponds with
- 156: * the parent Role most recently added.
- 157: *
- 158: * If the Role does not have any parents, then an empty array is returned.
- 159: *
- 162: */
- 164: {
- 167: }
- 171: /**
- 172: * Returns TRUE if $role inherits from $inherit.
- 173: *
- 174: * If $onlyParents is TRUE, then $role must inherit directly from
- 175: * $inherit in order to return TRUE. By default, this method looks
- 176: * through the entire inheritance DAG to determine whether $role
- 177: * inherits from $inherit through its ancestor Roles.
- 178: *
- 184: */
- 186: {
- 194: }
- 199: }
- 200: }
- 203: }
- 207: /**
- 208: * Removes the Role from the list.
- 209: *
- 213: */
- 215: {
- 229: }
- 230: }
- 236: }
- 237: }
- 238: }
- 241: }
- 245: /**
- 246: * Removes all Roles from the list.
- 247: *
- 249: */
- 251: {
- 260: }
- 261: }
- 264: }
- 268: /********************* resources ****************d*g**/
- 272: /**
- 273: * Adds a Resource having an identifier unique to the list.
- 274: *
- 280: */
- 282: {
- 287: }
- 292: }
- 300: }
- 304: /**
- 305: * Returns TRUE if the Resource exists in the list.
- 308: */
- 310: {
- 313: }
- 317: /**
- 318: * Checks whether Resource is valid and exists in the list.
- 323: */
- 325: {
- 331: }
- 332: }
- 336: /**
- 337: * Returns TRUE if $resource inherits from $inherit.
- 338: *
- 339: * If $onlyParents is TRUE, then $resource must inherit directly from
- 340: * $inherit in order to return TRUE. By default, this method looks
- 341: * through the entire inheritance tree to determine whether $resource
- 342: * inherits from $inherit through its ancestor Resources.
- 343: *
- 349: */
- 351: {
- 357: }
- 365: }
- 371: }
- 372: }
- 375: }
- 379: /**
- 380: * Removes a Resource and all of its children.
- 381: *
- 385: */
- 387: {
- 393: }
- 399: }
- 405: }
- 406: }
- 407: }
- 412: }
- 416: /**
- 417: * Removes all Resources.
- 418: *
- 420: */
- 422: {
- 427: }
- 428: }
- 429: }
- 433: }
- 437: /********************* defining rules ****************d*g**/
- 441: /**
- 442: * Adds an "allow" rule to the list. A rule is added that would allow one
- 443: * or more Roles access to [certain $privileges upon] the specified Resource(s).
- 444: *
- 445: * If either $roles or $resources is Permission::ALL, then the rule applies to all Roles or all Resources,
- 446: * respectively. Both may be Permission::ALL in order to work with the default rule of the ACL.
- 447: *
- 448: * The $privileges parameter may be used to further specify that the rule applies only
- 449: * to certain privileges upon the Resource(s) in question. This may be specified to be a single
- 450: * privilege with a string, and multiple privileges may be specified as an array of strings.
- 451: *
- 452: * If $assertion is provided, then its assert() method must return TRUE in order for
- 453: * the rule to apply. If $assertion is provided with $roles, $resources, and $privileges all
- 454: * equal to NULL, then a rule will imply a type of DENY when the rule's assertion fails.
- 455: *
- 461: */
- 463: {
- 466: }
- 470: /**
- 471: * Adds a "deny" rule to the list. A rule is added that would deny one
- 472: * or more Roles access to [certain $privileges upon] the specified Resource(s).
- 473: *
- 474: * If either $roles or $resources is Permission::ALL, then the rule applies to all Roles or all Resources,
- 475: * respectively. Both may be Permission::ALL in order to work with the default rule of the ACL.
- 476: *
- 477: * The $privileges parameter may be used to further specify that the rule applies only
- 478: * to certain privileges upon the Resource(s) in question. This may be specified to be a single
- 479: * privilege with a string, and multiple privileges may be specified as an array of strings.
- 480: *
- 481: * If $assertion is provided, then its assert() method must return TRUE in order for
- 482: * the rule to apply. If $assertion is provided with $roles, $resources, and $privileges all
- 483: * equal to NULL, then a rule will imply a type of ALLOW when the rule's assertion fails.
- 484: *
- 490: */
- 492: {
- 495: }
- 499: /**
- 500: * Removes "allow" permissions from the list. The rule is removed only in the context
- 501: * of the given Roles, Resources, and privileges. Existing rules to which the remove
- 502: * operation does not apply would remain in the
- 503: *
- 508: */
- 509: public function removeAllow($roles = self::ALL, $resources = self::ALL, $privileges = self::ALL)
- 510: {
- 513: }
- 517: /**
- 518: * Removes "deny" restrictions from the list. The rule is removed only in the context
- 519: * of the given Roles, Resources, and privileges. Existing rules to which the remove
- 520: * operation does not apply would remain in the
- 521: *
- 526: */
- 527: public function removeDeny($roles = self::ALL, $resources = self::ALL, $privileges = self::ALL)
- 528: {
- 531: }
- 535: /**
- 536: * Performs operations on Access Control List rules.
- 537: *
- 546: */
- 548: {
- 549: // ensure that all specified Roles exist; normalize input to array of Roles or NULL
- 556: }
- 560: }
- 561: }
- 563: // ensure that all specified Resources exist; normalize input to array of Resources or NULL
- 570: }
- 574: }
- 575: }
- 577: // normalize privileges to array
- 583: }
- 595: }
- 600: }
- 601: }
- 602: }
- 603: }
- 611: }
- 622: }
- 624: }
- 627: }
- 633: }
- 634: }
- 635: }
- 636: }
- 637: }
- 638: }
- 639: }
- 643: /********************* querying the ACL ****************d*g**/
- 647: /**
- 648: * Returns TRUE if and only if the Role has access to the Resource.
- 649: *
- 650: * If either $role or $resource is Permission::ALL, then the query applies to all Roles or all Resources,
- 651: * respectively. Both may be Permission::ALL to query whether the ACL has a "blacklist" rule
- 652: * (allow everything to all). By default, Permission creates a "whitelist" rule (deny
- 653: * everything to all), and this method would return FALSE unless this default has
- 654: * been overridden (i.e., by executing $acl->allow()).
- 655: *
- 656: * If a $privilege is not provided, then this method returns FALSE if and only if the
- 657: * Role is denied access to at least one privilege upon the Resource. In other words, this
- 658: * method returns TRUE if and only if the Role is allowed all privileges on the Resource.
- 659: *
- 660: * This method checks Role inheritance using a depth-first traversal of the Role list.
- 661: * The highest priority parent (i.e., the parent most recently added) is checked first,
- 662: * and its respective parents are checked similarly before the lower-priority parents of
- 663: * the Role are checked.
- 664: *
- 670: */
- 672: {
- 677: }
- 679: }
- 685: }
- 687: }
- 690: // query on all privileges
- 692: // depth-first search on $role if it is not 'allRoles' pseudo-parent
- 695: }
- 697: // look for rule on 'allRoles' psuedo-parent
- 700: if (self::DENY === ($ruleTypeOnePrivilege = $this->getRuleType($resource, NULL, $privilege))) {
- 703: }
- 704: }
- 708: }
- 709: }
- 711: // try next Resource
- 717: // query on one privilege
- 719: // depth-first search on $role if it is not 'allRoles' pseudo-parent
- 720: if ($role !== NULL && NULL !== ($result = $this->roleDFSOnePrivilege($role, $resource, $privilege))) {
- 722: }
- 724: // look for rule on 'allRoles' pseudo-parent
- 732: }
- 734: // try next Resource
- 738: }
- 742: }
- 746: /**
- 749: */
- 751: {
- 753: }
- 757: /**
- 760: */
- 762: {
- 764: }
- 768: /********************* internals ****************d*g**/
- 772: /**
- 773: * Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule.
- 774: * allowing/denying $role access to all privileges upon $resource
- 775: *
- 776: * This method returns TRUE if a rule is found and allows access. If a rule exists and denies access,
- 777: * then this method returns FALSE. If no applicable rule is found, then this method returns NULL.
- 778: *
- 782: */
- 784: {
- 794: }
- 795: }
- 796: }
- 799: }
- 803: /**
- 804: * Visits a $role in order to look for a rule allowing/denying $role access to all privileges upon $resource.
- 805: *
- 806: * This method returns TRUE if a rule is found and allows access. If a rule exists and denies access,
- 807: * then this method returns FALSE. If no applicable rule is found, then this method returns NULL.
- 808: *
- 809: * This method is used by the internal depth-first search algorithm and may modify the DFS data structure.
- 810: *
- 815: */
- 817: {
- 822: }
- 823: }
- 826: }
- 827: }
- 832: }
- 835: }
- 839: /**
- 840: * Performs a depth-first search of the Role DAG, starting at $role, in order to find a rule.
- 841: * allowing/denying $role access to a $privilege upon $resource
- 842: *
- 843: * This method returns TRUE if a rule is found and allows access. If a rule exists and denies access,
- 844: * then this method returns FALSE. If no applicable rule is found, then this method returns NULL.
- 845: *
- 850: */
- 852: {
- 860: if (NULL !== ($result = $this->roleDFSVisitOnePrivilege($role, $resource, $privilege, $dfs))) {
- 862: }
- 863: }
- 864: }
- 867: }
- 871: /**
- 872: * Visits a $role in order to look for a rule allowing/denying $role access to a $privilege upon $resource.
- 873: *
- 874: * This method returns TRUE if a rule is found and allows access. If a rule exists and denies access,
- 875: * then this method returns FALSE. If no applicable rule is found, then this method returns NULL.
- 876: *
- 877: * This method is used by the internal depth-first search algorithm and may modify the DFS data structure.
- 878: *
- 884: */
- 886: {
- 889: }
- 893: }
- 900: }
- 904: /**
- 905: * Returns the rule type associated with the specified Resource, Role, and privilege.
- 906: * combination.
- 907: *
- 908: * If a rule does not exist or its attached assertion fails, which means that
- 909: * the rule is not applicable, then this method returns NULL. Otherwise, the
- 910: * rule type applies and is returned as either ALLOW or DENY.
- 911: *
- 912: * If $resource or $role is Permission::ALL, then this means that the rule must apply to
- 913: * all Resources or Roles, respectively.
- 914: *
- 915: * If $privilege is Permission::ALL, then the rule must apply to all privileges.
- 916: *
- 917: * If all three parameters are Permission::ALL, then the default ACL rule type is returned,
- 918: * based on whether its assertion method passes.
- 919: *
- 924: */
- 926: {
- 927: // get the rules for the $resource and $role
- 930: }
- 932: // follow $privilege
- 938: }
- 944: }
- 946: // check assertion if necessary
- 947: if ($rule['assert'] === NULL || $rule['assert']->assert($this, $role, $resource, $privilege)) {
- 958: }
- 959: }
- 963: /**
- 964: * Returns the rules associated with a Resource and a Role, or NULL if no such rules exist.
- 965: *
- 966: * If either $resource or $role is Permission::ALL, this means that the rules returned are for all Resources or all Roles,
- 967: * respectively. Both can be Permission::ALL to return the default rule set for all Resources and all Roles.
- 968: *
- 969: * If the $create parameter is TRUE, then a rule set is first created and then returned to the caller.
- 970: *
- 975: */
- 977: {
- 978: // follow $resource
- 983: }
- 988: }
- 990: }
- 995: // follow $role
- 1001: }
- 1003: }
- 1005: }
- 1011: }
- 1013: }
- 1016: }
- 1018: }