equal
deleted
inserted
replaced
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`: |