[ Index ]

PHP Cross Reference of ACL Module

title

Body

[close]

/install/ -> Readme.txt (source)

   1  Contents:
   2  
   3  1) Preliminaries: What does this extension do?
   4  - How does ACL work?
   5  - Features of this extension
   6  - Limitations of this extension
   7  - How does ACL differ from RBAC?
   8  - Installation
   9  2) How can I use this extension? 
  10  3) Internals
  11  4) Possible Improvements
  12  5) Known Bugs**
  13  6) Versions
  14  
  15  
  16  
  17  
  18  1) What does this extension do?
  19  --------------------------------
  20      
  21    This extension provides a full-fledged implementation of ACL-based access     control. It's ideas are heavily leaned on the way cakePHP implements ACL, but extended both in convenience and power.  
  22      
  23      
  24  - How does ACL work?
  25  ---------------------
  26      
  27  In the following I'll only elucidate the really important concepts inherent to ACL - and I'll try to be as brief as possible. For detailed description of how ACL works, delve into specialized texts.
  28      
  29  Every ACL-system consists of at least two types: the ACOs (Access Control Objects) and AROs (Access Request Objects).
  30  ACOs are all the objects which are accessed (=> passive behavior), in particular on which specific actions are performed. Their counterpart are the AROs. Those objects take the active part, they try to perform specific actions on the ACOs. 
  31                                                                                                     
  32  Each single ARO-node can be linked to several ACOs. All connections between AROs and ACOs also indicate what actions may be performed by the involved ARO-node on the involved ACO-node.  In addition to that, both ACOs and AROs may be located in a hierarchy. Therefore they can have parents, inheriting the permissions of the parent node.
  33      
  34  If an action is to be performed, a connection between the ACO and ARO is sought, which has to grant the specified action. If no such connection is found, or if the connection does not grant the desired action, the access is denied.
  35      
  36      
  37      
  38  - Features
  39  ----------------------
  40      
  41  - multiple groups for each node (both ACO and ARO) 
  42  - Unlimited depth in hierarchy
  43  - supports also access control filters with backward-compatible syntax
  44  - non-recursive permission lookup 
  45  - convenient, integrated interface
  46  - transactions as well as exceptions upon crucial errors
  47      
  48  - Limitations
  49  ----------------------
  50  - Due to parametrized static method calls this extension is limited to PHP versions >= 5.3.0. 
  51  - this extension supports solely positive rights-management
  52   => the access check only checks if you are explicitely allowed to do something,  it doesn't checkif you are explicitely _denied_ access
  53  
  54  - A fellow told me that INNER JOINs have a different syntax (regarding `` and so on) on different DBMS. The extension was developed with MySQL and was never tested with competitors such as Oracle or PGSQL but it should be an easy task to adjust the things if I knew what to change.
  55  
  56  - The system currently requires numerical primary keys which are all named "id" for both your ACOs and AROs. I keep my eyes peeled but nothing has shown up yet to remedy that in an easy way.
  57      
  58      
  59  - How does ACL differ from RBAC?
  60  -------------------------------
  61      
  62  As the name already states, Role-based Access Control grants or denies permissions through roles. 
  63  Access Control Lists uses a more general approach using generalized objects and their relations. In general, ACL is more suited if the access control has to be fine-grained at the object-/document-level. That is, if specific permissions to specific ACOs attached to AROs take precedence over specific permissions to types of ACOs attached to specific users. 
  64      
  65  The gist is that the builtin Yii RBAC-system only allows so-called business-rules to check if a given object "belongs" to the given user (or one of his groups).
  66  This has several drawbacks:
  67  
  68  1) In order to check the business-rules Yii has to load every (possible suitable) single rule out of the database and execute it (it's plain PHP-code)
  69  
  70  2) Those rules are fixed (PHP-expressions). Therefore one is not able to alter the permissions dynamically without rewriting all the rules.
  71  
  72  3) It's a bad habit to store PHP-Code in the database. 
  73  
  74  4) Those rules tend to be broader and thus there is no really convient "fine-grained" control possible. Of course it's possible to achieve the same things possible with ACL using RBAC. Even with a Smart you can reach 70 miles/h.
  75          
  76          
  77          
  78  - Installation
  79  -------------
  80      
  81  1) Copy the files in your "modules"-section of your application
  82  2) Edit main.php as follows:
  83  
  84  ~~~
  85  [php]
  86  'import'=>array(
  87          'application.modules.acl.components.*',
  88          'application.modules.acl.models.*'
  89        )
  90  ~~~
  91  
  92  
  93  3) Create the necessary tables using sql.txt
  94  4) You are done.
  95  
  96  
  97  Installation of the Access Control Filter: 
  98  (It's not possible to introduce a better procedure, as the core development team has rejected to make things protected.)
  99      
 100  First, you have to update the framework itself. Go to framework/web/auth/CAccessControlFilter.php
 101  and change line 67 to:
 102  
 103  ~~~
 104  [php]
 105  protected $_rules=array();
 106  ~~~    
 107  
 108  In order to use the new Filter, overwrite the method "filterAccessControl" in your controllers:
 109  
 110  ~~~
 111  [php]
 112  public function filterAccessControl($filterChain) {
 113              $filter = new ExtAccessControlFilter;
 114              $filter->setRules($this->accessRules());
 115              $filter->filter($filterChain);
 116          }
 117  ~~~      
 118  
 119  You are done. There are no changes in syntax or behavior to keep in mind. Roles correspond to User-Groups (and thus Aro-Objects). Everything works just as it did before.
 120          
 121          
 122  2) How can I use this extension? 
 123  ---------------------------------
 124  
 125      
 126  Configuration:
 127        
 128  In order to use this feature, you have add the "RequestingActiveRecordBehavior" to your Model or you can derive your requesting model 
 129  (usually the User) from "RequestingActiveRecord" instead of "CActiveRecord".
 130  (see RestrictedActiveRecord::model)
 131   e.g.:       
 132  
 133  ~~~
 134  [php]
 135  class User extends RequestingActiveRecord{ ... }
 136  ~~~
 137  
 138  
 139  Secondly, you do the same with the objects to restrict access on - you just use "RestrictedActiveRecordBehavior" as the behavior or "RestrictedActiveRecord" as the base class. 
 140  
 141  From now on, whenever you try to to select, update or delete records using the ActiveRecord-objects, access will be automatically checked and you will only get the objects to which the user has access.
 142  Feel free to do such stuff:      
 143  
 144  ~~~
 145  [php]
 146  $img = Image::model()->find(...)  // is this my object?
 147            $img->key = value;
 148            $img->save();                     //May I update this object? (notice: an exception is thrown 

 149                                          // if rules are violated)

 150            
 151            $images = Image::model()->findAll(...) //You only get the ones you have access to
 152  ~~~
 153  
 154  That's it. You don't believe it? Just try it:->
 155              
 156  Take a glance at the behaviors:
 157  - by default, every user can create a new object of every type
 158  - by default, a user has all rights on the objects he himself created
 159  
 160  - if the user is a guest, his rights are equal to the group named "Guest" (see the strategy-configuration to change this)
 161             => if you don't create such a group and assign rights, he has no rights
 162             => assign all rights for guests to this group and NOWHERE else
 163           => you can bypass the Access Check setting  RestrictedActiveRecord::byPassCheck to true.
 164           => you can "view" the database through the "glasses" of any other ARO than the current user: take a squint at RestrictedActiveRecord::inAttendance
 165           
 166  This may be necessary in certain circumstances, for example if guests can create objects  and may update them (employing an authentication mechanism such as cookies) but he himself isn't represented by any dedicated ARO-object (because he is a guest). To anyway allow him to update his own objects, you can bypass the check easily.
 167              
 168          
 169               
 170  - Rights Management:
 171  ---------------------------
 172              
 173              
 174  
 175  ~~~
 176  [php]
 177  //Recall: we need the activeRecord, not the identity

 178          $user = User::model()->findByPk(Yii::app()->user->id);
 179          
 180          //$activeRecord can be of any type derived vom CActiveRecord

 181          $obj  = new $activeRecord();
 182          $obj->save();      
 183              
 184              //See later for actions

 185              $user->grant($obj, $actions);
 186          $user->deny($obj, $actions);
 187          $user->may($obj, $action);
 188          
 189          //$group can be any valid alias-string             

 190          $group = "MyGroup";
 191          
 192          //checks whether the user is in the given group

 193          $user->is($group);
 194          
 195          //note: if strict-mode is disabled, the group will automatically be created upon the first access

 196          //otherwise, you have to use the RGroup-Class to create the group

 197          $user->join($group);
 198          $user->leave($group);
 199          
 200          // Note that it is possible to deny or grant rights multiple times, but it won't 

 201          // have any effect but letting the performance drop. 

 202  ~~~
 203  
 204          
 205          
 206  There are three possible syntaxes to denote an object :
 207  1) Pass the object directly, e.g.: $user->grant($obj, $actions);
 208  2) Use the unique identifier of the object, e.g.:
 209      $user->grant(array('model' => 'Image', 'foreign_key' => 'theID'), $actions);
 210  3) Use an alias (if the object has an alias):
 211      $user->grant("myAlias", $actions);
 212      
 213  Note: You can set the alias only if you access the ARO or ACO using RGroup/CGroup. If you use them only for grouping, you can use the implicit variant, which is probably the most convenient one.
 214      
 215  
 216  Identification of objects:
 217  -------------------------
 218  Every ACL-Object (Aro or Aco) can be dinstinguished using three techniques:
 219  
 220  a) The object itself (it's ID). This ID is automatically created when the object
 221     is instantiated. Most times you won't use this direct one. If you bother to         do, use RGroup or CGroup.
 222  
 223  b)  Using the unique associated: Most ACL-Objects correspond to a real object in             your database. You can therefore identify the ACL-Objects by their associated objects: array('model' => 'yourModel', 'foreign_key' => 'aNumericalID');
 224  
 225  c) Using an Alias. Not all ACL-Objects must directly correspond to real objects. Especially if you perform grouping, you may want to have virtual groups you don't have in your real application. For example "Guest" is such a group: If you don't use it anywhere else, why should you create a corresponding object in your database?
 226  You can create such groups using CGroup (ControlGroup => for AccessControlObjects) and RGroup(RequestGroup => for AccessRequestObjects).
 227  Note that you can assign aliases to every of your restricted or requesting objects, even if they don't represent a group.
 228  
 229  Example:
 230  ~~~
 231  [php] 
 232    
 233    $cGroup = new CGroup();
 234    $cGroup->alias = 'MyAlias';
 235    $cGroup->save();
 236    
 237    $aco = Image::model()->find(...);
 238    $aco->join($cGroup);
 239    // OR

 240    $aco->join('MyAlias');
 241  ~~~  
 242          
 243          
 244  - Actions:
 245  -------------------------
 246  
 247  Actions are represented by the Model "Action" and reside in {{action}}.
 248  The shipped actions are "create", "read", "update", "delete". They should neither be renamed nor removed, as the automatic functionality relies on them. In order to add a possible action, just add a row to your database. 
 249  This extension supports the wildcard '*', which will automatically be converted into all available actions.
 250  Please note that you can limit the actions which can be performed on a specific RestrictedActiveRecord by setting it's possibleActions (it's a static var!). 
 251  Examples:
 252  ~~~
 253  [php]
 254  
 255    $aro->grant($aco, array('read', 'update'));
 256    $aro->grant($aco, 'read, update');
 257    $aro->grant($aco, '* - create, delete'); //Corresponds to the preceding example if $aco::possibleActions = array('create', 'read', 'update', 'delete');

 258  ~~~
 259  
 260  Please keep in mind that "*"" is resolved immediately, so if you add actions later on, you will need to update your objects you granted "*" to.
 261  
 262         
 263  
 264  4) Possible Improvements
 265  -------------------------
 266        
 267  - introduce domains
 268  Currently, all objects of all models (aco, aro) are stored in the same tables. If you have different types of objects changing more or less often (images change faster than groups or user), it would improve the performance drastically to store both in separate tables. 
 269        
 270  - build a full-fledged ACP
 271  This has already been done on my behalf, but I recoded the base and the graphical interface is therefore not usable any more. This wish is actually the reason why the extension is shipped as a module. 
 272        
 273  
 274  
 275  5) Known Bugs
 276  --------------
 277    
 278    Fortunately, this chapter is empty again :->
 279  
 280  
 281  6) Versions
 282  --------------
 283  
 284  0.1:
 285  
 286  + proper removal of associated ACL-objects on deletion of the ActiveRecord
 287  
 288  
 289  + bugfix for errors in conjunction with DataProviders
 290  
 291  
 292  
 293  0.2:
 294  
 295  + if strict-mode was disabled, automatic creation of Aro-Collections did not work 
 296  properly in all cases. This has been fixed.
 297  
 298  + The Access Control Filter has been added
 299  
 300  + some minor changes (most important: CRestrictedActiveRecord) which do not effect exterior
 301  
 302  
 303  
 304  0.3 (Current Version):
 305  
 306   + fully recoded 
 307   
 308   + added switchable strategies (shipped strategy: Path Materialization) 
 309   
 310   + abstracted actions 
 311   
 312   + enabled limitation of actions and a new syntax for action-definitions
 313   
 314   + added behaviors
 315   
 316   + introduced several more convenient interfaces
 317   
 318   


Generated: Sun Jul 1 19:24:45 2012 Cross-referenced by PHPXref 0.7.1