doc/tutorials/advanced/part02_security.rst
branch3.26
changeset 12464 d26382fc15d8
parent 12463 18b6d2493578
child 12400 a9f15d3d65f9
equal deleted inserted replaced
12463:18b6d2493578 12464:d26382fc15d8
    50 * to some RQL expressions: users get access if the expression returns some results
    50 * to some RQL expressions: users get access if the expression returns some results
    51 
    51 
    52 To implement the read security defined earlier, groups are not enough, we'll
    52 To implement the read security defined earlier, groups are not enough, we'll
    53 need some RQL expression. Here is the idea:
    53 need some RQL expression. Here is the idea:
    54 
    54 
    55 * add a `visibility` attribute on Folder, File and Comment, which may be one of
    55 * add a `visibility` attribute on `Folder`, `File` and `Comment`, which may be one of
    56   the value explained above
    56   the value explained above
    57 
    57 * add a `may_be_read_by` relation from `Folder`, `File` and `Comment` to `users`,
    58 * add a `may_be_read_by` relation from Folder, File and Comment to users,
    58 
    59   which will define who can see the entity
    59   which will define who can see the entity
    60 
    60 
    61 * security propagation will be done in hook.
    61 * security propagation will be done in hook.
    62 
    62 
    63 So the first thing to do is to modify my cube's :file:`schema.py` to define those
    63 So the first thing to do is to modify my cube's :file:`schema.py` to define those
    85 	subject = ('Folder', 'File', 'Comment',)
    85 	subject = ('Folder', 'File', 'Comment',)
    86 	object = 'CWUser'
    86 	object = 'CWUser'
    87 
    87 
    88 We can note the following points:
    88 We can note the following points:
    89 
    89 
    90 * we've added a new `visibility` attribute to folder, file, image and comment
    90 * we've added a new `visibility` attribute to `Folder`, `File`, `Image` and `Comment`
    91   using a `RelationDefinition`
    91   using a `RelationDefinition`
    92 
    92 
    93 * `cardinality = '11'` means this attribute is required. This is usually hidden
    93 * `cardinality = '11'` means this attribute is required. This is usually hidden
    94   under the `required` argument given to the `String` constructor, but we can
    94   under the `required` argument given to the `String` constructor, but we can
    95   rely on this here (same thing for StaticVocabularyConstraint, which is usually
    95   rely on this here (same thing for StaticVocabularyConstraint, which is usually
   184 
   184 
   185 In our case we will:
   185 In our case we will:
   186 
   186 
   187 * on entity creation, schedule an operation that will set default visibility
   187 * on entity creation, schedule an operation that will set default visibility
   188 
   188 
   189 * when a "parent" relation is added, propagate parent's visibility unless the
   189 * when a `parent` relation is added, propagate parent's visibility unless the
   190   child already has a visibility set
   190   child already has a visibility set
   191 
   191 
   192 Here is the code in cube's :file:`hooks.py`:
   192 Here is the code in cube's :file:`hooks.py`:
   193 
   193 
   194 .. sourcecode:: python
   194 .. sourcecode:: python
   228 * hooks are application objects, hence have selectors that should match entity or
   228 * hooks are application objects, hence have selectors that should match entity or
   229   relation types to which the hook applies. To match a relation type, we use the
   229   relation types to which the hook applies. To match a relation type, we use the
   230   hook specific `match_rtype` selector.
   230   hook specific `match_rtype` selector.
   231 
   231 
   232 * usage of `DataOperationMixIn`: instead of adding an operation for each added entity,
   232 * usage of `DataOperationMixIn`: instead of adding an operation for each added entity,
   233   DataOperationMixIn allows to create a single one and to store entity's eids to be
   233   `DataOperationMixIn` allows to create a single one and to store entity's eids to be
   234   processed in the transaction data. This is a good pratice to avoid heavy
   234   processed in the transaction data. This is a good pratice to avoid heavy
   235   operations manipulation cost when creating a lot of entities in the same
   235   operations manipulation cost when creating a lot of entities in the same
   236   transaction.
   236   transaction.
   237 
   237 
   238 * the `precommit_event` method of the operation will be called at transaction's
   238 * the `precommit_event` method of the operation will be called at transaction's
   249   - `self.eidfrom` / `self.eidto` are the eid of the subject / object entity on
   249   - `self.eidfrom` / `self.eidto` are the eid of the subject / object entity on
   250     'after_add_relation' events (you may also get the relation type using
   250     'after_add_relation' events (you may also get the relation type using
   251     `self.rtype`)
   251     `self.rtype`)
   252 
   252 
   253 The `parent` visibility value is used to tell "propagate using parent security"
   253 The `parent` visibility value is used to tell "propagate using parent security"
   254 because we want that attribute to be required, so we can't use None value else
   254 because we want that attribute to be required, so we can't use `None` value else
   255 we'll get an error before we get any chance to propagate...
   255 we'll get an error before we get any chance to propagate...
   256 
   256 
   257 Now, we also want to propagate the `may_be_read_by` relation. Fortunately,
   257 Now, we also want to propagate the `may_be_read_by` relation. Fortunately,
   258 CubicWeb provides some base hook classes for such things, so we only have to add
   258 CubicWeb provides some base hook classes for such things, so we only have to add
   259 the following code to :file:`hooks.py`:
   259 the following code to :file:`hooks.py`: