doc/book/en/B0015-define-permissions.en.txt
branchtls-sprint
changeset 1715 cba9f175da2d
parent 1585 b86448eaed66
child 2175 16d3c37c5d28
equal deleted inserted replaced
1714:a721966779be 1715:cba9f175da2d
       
     1 .. -*- coding: utf-8 -*-
       
     2 
       
     3 The security model
       
     4 ------------------
       
     5 
       
     6 The security model of `cubicWeb` is based on `Access Control List`. 
       
     7 The main principles are:
       
     8 
       
     9 * users and groups of users
       
    10 * a user belongs to at least one group of user
       
    11 * permissions (read, update, create, delete)
       
    12 * permissions are assigned to groups (and not to users)
       
    13 
       
    14 For `CubicWeb` in particular:
       
    15 
       
    16 * we associate rights at the enttities/relations schema level
       
    17 * for each entity, we distinguish four kind of permissions: read,
       
    18   add, update and delete
       
    19 * for each relation, we distinguish three king of permissions: read,
       
    20   add and delete (we can not modify a relation)
       
    21 * the basic groups are: Administrators, Users and Guests
       
    22 * by default, users belongs to the group Users
       
    23 * there is a virtual group called `Owners users` to which we
       
    24   can associate only deletion and update permissions
       
    25 * we can not add users to the `Owners users` group, they are
       
    26   implicetely added to it according to the context of the objects
       
    27   they own
       
    28 * the permissions of this group are only be checked on update/deletion
       
    29   actions if all the other groups the user belongs does not provide
       
    30   those permissions
       
    31 
       
    32   
       
    33 Permissions definition
       
    34 ``````````````````````
       
    35 
       
    36 Setting permissions is done with the attribute `permissions` of entities and
       
    37 relation types. It defines a dictionary where the keys are the access types
       
    38 (action), and the values are the authorized groups or expressions.
       
    39 
       
    40 For an entity type, the possible actions are `read`, `add`, `update` and
       
    41 `delete`.
       
    42 
       
    43 For a relation type, the possible actions are `read`, `add`, and `delete`.
       
    44 
       
    45 For each access type, a tuple indicates the name of the authorized groups and/or
       
    46 one or multiple RQL expressions to satisfy to grant access. The access is
       
    47 provided once the user is in the listed groups or one of the RQL condition is
       
    48 satisfied.
       
    49 
       
    50 The standard groups are :
       
    51 
       
    52 * `guests`
       
    53 
       
    54 * `users`
       
    55 
       
    56 * `managers`
       
    57 
       
    58 * `owners` : virtual group corresponding to the entity's owner.
       
    59   This can only be used for the actions `update` and `delete` of an entity
       
    60   type.
       
    61 
       
    62 It is also possible to use specific groups if they are defined in the precreate 
       
    63 of the cube (``migration/precreate.py``).
       
    64 
       
    65 
       
    66 Use of RQL expression for writing rights
       
    67 ````````````````````````````````````````
       
    68 
       
    69 It is possible to define RQL expression to provide update permission 
       
    70 (`add`, `delete` and `update`) on relation and entity types.
       
    71 
       
    72 RQL expression for entity type permission :
       
    73 
       
    74 * you have to use the class `ERQLExpression`
       
    75 
       
    76 * the used expression corresponds to the WHERE statement of an RQL query
       
    77 
       
    78 * in this expression, the variables X and U are pre-defined references
       
    79   respectively on the current entity (on which the action is verified) and
       
    80   on the user who send the request
       
    81 
       
    82 * it is possible to use, in this expression, a special relation 
       
    83   "has_<ACTION>_permission" where the subject is the user and the 
       
    84   object is a any variable, meaning that the user needs to have
       
    85   permission to execute the action <ACTION> on the entities related
       
    86   to this variable 
       
    87 
       
    88 For RQL expressions on a relation type, the principles are the same except 
       
    89 for the following :
       
    90 
       
    91 * you have to use the class `RQLExpression` in the case of a non-final relation
       
    92 
       
    93 * in the expression, the variables S, O and U are pre-defined references
       
    94   to respectively the subject and the object of the current relation (on
       
    95   which the action is being verified) and the user who executed the query
       
    96 
       
    97 * we can also defined rights on attributes of an entity (non-final relation),
       
    98   knowing that : 
       
    99 
       
   100   - to defines RQL expression, we have to use the class `ERQLExpression`
       
   101     in which X represents the entity the attribute belongs to
       
   102 
       
   103   - the permissions `add` and `delete` are equivalent. Only `add`/`read`
       
   104     are actually taken in consideration.
       
   105 
       
   106 In addition to that the entity type `EPermission` from the standard library
       
   107 allow to build very complex and dynamic security architecture. The schema of
       
   108 this entity type is as follow : ::
       
   109 
       
   110     class EPermission(MetaEntityType):
       
   111 	"""entity type that may be used to construct some advanced security configuration
       
   112 	"""
       
   113 	name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
       
   114 	require_group = SubjectRelation('EGroup', cardinality='+*',
       
   115 					description=_('groups to which the permission is granted'))
       
   116 	require_state = SubjectRelation('State',
       
   117 				    description=_("entity'state in which the permission is applyable"))
       
   118 	# can be used on any entity
       
   119 	require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
       
   120 					    description=_("link a permission to the entity. This "
       
   121 							  "permission should be used in the security "
       
   122 							  "definition of the entity's type to be useful."))
       
   123 
       
   124 
       
   125 Example of configuration ::
       
   126 
       
   127 
       
   128     ...
       
   129 
       
   130     class Version(EntityType):
       
   131 	"""a version is defining the content of a particular project's release"""
       
   132 
       
   133 	permissions = {'read':   ('managers', 'users', 'guests',),
       
   134 		       'update': ('managers', 'logilab', 'owners',),
       
   135 		       'delete': ('managers', ),
       
   136 		       'add':    ('managers', 'logilab',
       
   137 				  ERQLExpression('X version_of PROJ, U in_group G,'
       
   138 						 'PROJ require_permission P, P name "add_version",'
       
   139 						 'P require_group G'),)}
       
   140 
       
   141     ...
       
   142 
       
   143     class version_of(RelationType):
       
   144 	"""link a version to its project. A version is necessarily linked to one and only one project.
       
   145 	"""
       
   146 	permissions = {'read':   ('managers', 'users', 'guests',),
       
   147 		       'delete': ('managers', ),
       
   148 		       'add':    ('managers', 'logilab',
       
   149 				  RRQLExpression('O require_permission P, P name "add_version",'
       
   150 						 'U in_group G, P require_group G'),)
       
   151 		       }
       
   152 	inlined = True
       
   153 
       
   154 This configuration indicates that an entity `EPermission` named
       
   155 "add_version" can be associated to a project and provides rights to create
       
   156 new versions on this project to specific groups. It is important to notice that :
       
   157 
       
   158 * in such case, we have to protect both the entity type "Version" and the relation
       
   159   associating a version to a project ("version_of")
       
   160 
       
   161 * because of the genricity of the entity type `EPermission`, we have to execute
       
   162   a unification with the groups and/or the states if necessary in the expression
       
   163   ("U in_group G, P require_group G" in the above example)
       
   164 
       
   165 Use of RQL expression for reading rights
       
   166 ````````````````````````````````````````
       
   167 
       
   168 The principles are the same but with the following restrictions :
       
   169 
       
   170 * we can not use `RRQLExpression` on relation types for reading
       
   171 
       
   172 * special relations "has_<ACTION>_permission" can not be used
       
   173 
       
   174 
       
   175 Note on the use of RQL expression for `add` permission
       
   176 ``````````````````````````````````````````````````````
       
   177 Potentially, the use of an RQL expression to add an entity or a relation
       
   178 can cause problems for the user interface, because if the expression uses
       
   179 the entity or the relation to create, then we are not able to verify the 
       
   180 permissions before we actually add the entity (please note that this is
       
   181 not a problem for the RQL server at all, because the permissions checks are
       
   182 done after the creation). In such case, the permission check methods 
       
   183 (check_perm, has_perm) can indicate that the user is not allowed to create 
       
   184 this entity but can obtain the permission. 
       
   185 To compensate this problem, it is usually necessary, for such case,
       
   186 to use an action that reflects the schema permissions but which enables
       
   187 to check properly the permissions so that it would show up if necessary.
       
   188