diff -r 01210bb805dc -r b86448eaed66 doc/book/en/B0015-define-permissions.en.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/book/en/B0015-define-permissions.en.txt Wed Apr 15 18:16:12 2009 +0200 @@ -0,0 +1,188 @@ +.. -*- coding: utf-8 -*- + +The security model +------------------ + +The security model of `cubicWeb` is based on `Access Control List`. +The main principles are: + +* users and groups of users +* a user belongs to at least one group of user +* permissions (read, update, create, delete) +* permissions are assigned to groups (and not to users) + +For `CubicWeb` in particular: + +* we associate rights at the enttities/relations schema level +* for each entity, we distinguish four kind of permissions: read, + add, update and delete +* for each relation, we distinguish three king of permissions: read, + add and delete (we can not modify a relation) +* the basic groups are: Administrators, Users and Guests +* by default, users belongs to the group Users +* there is a virtual group called `Owners users` to which we + can associate only deletion and update permissions +* we can not add users to the `Owners users` group, they are + implicetely added to it according to the context of the objects + they own +* the permissions of this group are only be checked on update/deletion + actions if all the other groups the user belongs does not provide + those permissions + + +Permissions definition +`````````````````````` + +Setting permissions is done with the attribute `permissions` of entities and +relation types. It defines a dictionary where the keys are the access types +(action), and the values are the authorized groups or expressions. + +For an entity type, the possible actions are `read`, `add`, `update` and +`delete`. + +For a relation type, the possible actions are `read`, `add`, and `delete`. + +For each access type, a tuple indicates the name of the authorized groups and/or +one or multiple RQL expressions to satisfy to grant access. The access is +provided once the user is in the listed groups or one of the RQL condition is +satisfied. + +The standard groups are : + +* `guests` + +* `users` + +* `managers` + +* `owners` : virtual group corresponding to the entity's owner. + This can only be used for the actions `update` and `delete` of an entity + type. + +It is also possible to use specific groups if they are defined in the precreate +of the cube (``migration/precreate.py``). + + +Use of RQL expression for writing rights +```````````````````````````````````````` + +It is possible to define RQL expression to provide update permission +(`add`, `delete` and `update`) on relation and entity types. + +RQL expression for entity type permission : + +* you have to use the class `ERQLExpression` + +* the used expression corresponds to the WHERE statement of an RQL query + +* in this expression, the variables X and U are pre-defined references + respectively on the current entity (on which the action is verified) and + on the user who send the request + +* it is possible to use, in this expression, a special relation + "has__permission" where the subject is the user and the + object is a any variable, meaning that the user needs to have + permission to execute the action on the entities related + to this variable + +For RQL expressions on a relation type, the principles are the same except +for the following : + +* you have to use the class `RQLExpression` in the case of a non-final relation + +* in the expression, the variables S, O and U are pre-defined references + to respectively the subject and the object of the current relation (on + which the action is being verified) and the user who executed the query + +* we can also defined rights on attributes of an entity (non-final relation), + knowing that : + + - to defines RQL expression, we have to use the class `ERQLExpression` + in which X represents the entity the attribute belongs to + + - the permissions `add` and `delete` are equivalent. Only `add`/`read` + are actually taken in consideration. + +In addition to that the entity type `EPermission` from the standard library +allow to build very complex and dynamic security architecture. The schema of +this entity type is as follow : :: + + class EPermission(MetaEntityType): + """entity type that may be used to construct some advanced security configuration + """ + name = String(required=True, indexed=True, internationalizable=True, maxsize=100) + require_group = SubjectRelation('EGroup', cardinality='+*', + description=_('groups to which the permission is granted')) + require_state = SubjectRelation('State', + description=_("entity'state in which the permission is applyable")) + # can be used on any entity + require_permission = ObjectRelation('**', cardinality='*1', composite='subject', + description=_("link a permission to the entity. This " + "permission should be used in the security " + "definition of the entity's type to be useful.")) + + +Example of configuration :: + + + ... + + class Version(EntityType): + """a version is defining the content of a particular project's release""" + + permissions = {'read': ('managers', 'users', 'guests',), + 'update': ('managers', 'logilab', 'owners',), + 'delete': ('managers', ), + 'add': ('managers', 'logilab', + ERQLExpression('X version_of PROJ, U in_group G,' + 'PROJ require_permission P, P name "add_version",' + 'P require_group G'),)} + + ... + + class version_of(RelationType): + """link a version to its project. A version is necessarily linked to one and only one project. + """ + permissions = {'read': ('managers', 'users', 'guests',), + 'delete': ('managers', ), + 'add': ('managers', 'logilab', + RRQLExpression('O require_permission P, P name "add_version",' + 'U in_group G, P require_group G'),) + } + inlined = True + +This configuration indicates that an entity `EPermission` named +"add_version" can be associated to a project and provides rights to create +new versions on this project to specific groups. It is important to notice that : + +* in such case, we have to protect both the entity type "Version" and the relation + associating a version to a project ("version_of") + +* because of the genricity of the entity type `EPermission`, we have to execute + a unification with the groups and/or the states if necessary in the expression + ("U in_group G, P require_group G" in the above example) + +Use of RQL expression for reading rights +```````````````````````````````````````` + +The principles are the same but with the following restrictions : + +* we can not use `RRQLExpression` on relation types for reading + +* special relations "has__permission" can not be used + + +Note on the use of RQL expression for `add` permission +`````````````````````````````````````````````````````` +Potentially, the use of an RQL expression to add an entity or a relation +can cause problems for the user interface, because if the expression uses +the entity or the relation to create, then we are not able to verify the +permissions before we actually add the entity (please note that this is +not a problem for the RQL server at all, because the permissions checks are +done after the creation). In such case, the permission check methods +(check_perm, has_perm) can indicate that the user is not allowed to create +this entity but can obtain the permission. +To compensate this problem, it is usually necessary, for such case, +to use an action that reflects the schema permissions but which enables +to check properly the permissions so that it would show up if necessary. +