33 |
33 |
34 Built-in types for attributes |
34 Built-in types for attributes |
35 ````````````````````````````` |
35 ````````````````````````````` |
36 |
36 |
37 All `CubicWeb` built-in types are available : `String`, `Int`, `Float`, |
37 All `CubicWeb` built-in types are available : `String`, `Int`, `Float`, |
38 `Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` |
38 `Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` |
39 and `Password`. |
39 and `Password`. |
40 They are implicitely imported (as well as the special the function "_" |
40 They are implicitely imported (as well as the special the function "_" |
41 for translation :ref:`internationalization`). |
41 for translation :ref:`internationalization`). |
42 |
42 |
43 An attribute is defined in the schema as follows:: |
43 An attribute is defined in the schema as follows:: |
44 |
44 |
45 attr_name = attr_type(properties*) |
45 attr_name = attr_type(properties*) |
46 |
46 |
47 where `attr_type` is one of the type listed above and `properties` is |
47 where `attr_type` is one of the type listed above and `properties` is |
48 a list of the attribute needs to statisfy (see :ref:`properties` |
48 a list of the attribute needs to statisfy (see :ref:`properties` |
49 for more details). |
49 for more details). |
50 |
50 |
51 |
51 |
52 Meta-data |
52 Meta-data |
53 ````````` |
53 ````````` |
54 |
54 |
55 Each entity type has at least the following meta-relations : |
55 Each entity type has at least the following meta-relations : |
56 |
56 |
57 - `eid` (`Int`) |
57 - `eid` (`Int`) |
58 |
58 |
59 - `creation_date` (`Datetime`) |
59 - `creation_date` (`Datetime`) |
60 |
60 |
61 - `modification_date` (`Datetime`) |
61 - `modification_date` (`Datetime`) |
62 |
62 |
63 - `created_by` (`CWUser`) (which user created the entity) |
63 - `created_by` (`CWUser`) (which user created the entity) |
64 |
64 |
65 - `owned_by` (`CWUser`) (to whom the entity belongs; by default the |
65 - `owned_by` (`CWUser`) (to whom the entity belongs; by default the |
66 creator but not necessary, and it could have multiple owners) |
66 creator but not necessary, and it could have multiple owners) |
67 |
67 |
68 - `is` (`CWEType`) (of which type the entity is) |
68 - `is` (`CWEType`) (of which type the entity is) |
69 |
69 |
70 |
70 |
71 * relations can be defined by using `ObjectRelation` or `SubjectRelation`. |
71 * relations can be defined by using `ObjectRelation` or `SubjectRelation`. |
72 The first argument of `SubjectRelation` or `ObjectRelation` gives respectively |
72 The first argument of `SubjectRelation` or `ObjectRelation` gives respectively |
73 the object/subject entity type of the relation. This could be : |
73 the object/subject entity type of the relation. This could be : |
74 |
74 |
75 * a string corresponding to an entity type |
75 * a string corresponding to an entity type |
76 |
76 |
77 * a tuple of string corresponding to multiple entity types |
77 * a tuple of string corresponding to multiple entity types |
78 |
78 |
79 * special string such as follows : |
79 * special string such as follows : |
80 |
80 |
81 - "**" : all types of entities |
81 - "**" : all types of entities |
82 - "*" : all types of non-meta entities |
82 - "*" : all types of non-meta entities |
83 - "@" : all types of meta entities but not system entities (e.g. used for |
83 - "@" : all types of meta entities but not system entities (e.g. used for |
84 the basic schema description) |
84 the basic schema description) |
85 |
85 |
86 * it is possible to use the attribute `meta` to flag an entity type as a `meta` |
86 * it is possible to use the attribute `meta` to flag an entity type as a `meta` |
87 (e.g. used to describe/categorize other entities) |
87 (e.g. used to describe/categorize other entities) |
114 * `*`: 0..n |
114 * `*`: 0..n |
115 |
115 |
116 - `meta` : boolean indicating that the relation is a meta-relation (false by |
116 - `meta` : boolean indicating that the relation is a meta-relation (false by |
117 default) |
117 default) |
118 |
118 |
119 * optional properties for attributes : |
119 * optional properties for attributes : |
120 |
120 |
121 - `required` : boolean indicating if the attribute is required (false by default) |
121 - `required` : boolean indicating if the attribute is required (false by default) |
122 |
122 |
123 - `unique` : boolean indicating if the value of the attribute has to be unique |
123 - `unique` : boolean indicating if the value of the attribute has to be unique |
124 or not within all entities of the same type (false by default) |
124 or not within all entities of the same type (false by default) |
125 |
125 |
126 - `indexed` : boolean indicating if an index needs to be created for this |
126 - `indexed` : boolean indicating if an index needs to be created for this |
127 attribute in the database (false by default). This is useful only if |
127 attribute in the database (false by default). This is useful only if |
128 you know that you will have to run numerous searches on the value of this |
128 you know that you will have to run numerous searches on the value of this |
129 attribute. |
129 attribute. |
130 |
130 |
131 - `default` : default value of the attribute. In case of date types, the values |
131 - `default` : default value of the attribute. In case of date types, the values |
132 which could be used correspond to the RQL keywords `TODAY` and `NOW`. |
132 which could be used correspond to the RQL keywords `TODAY` and `NOW`. |
133 |
133 |
134 - `vocabulary` : specify static possible values of an attribute |
134 - `vocabulary` : specify static possible values of an attribute |
135 |
135 |
136 * optional properties of type `String` : |
136 * optional properties of type `String` : |
137 |
137 |
138 - `fulltextindexed` : boolean indicating if the attribute is part of |
138 - `fulltextindexed` : boolean indicating if the attribute is part of |
139 the full text index (false by default) (*applicable on the type `Byte` |
139 the full text index (false by default) (*applicable on the type `Byte` |
140 as well*) |
140 as well*) |
141 |
141 |
142 - `internationalizable` : boolean indicating if the value of the attribute |
142 - `internationalizable` : boolean indicating if the value of the attribute |
143 is internationalizable (false by default) |
143 is internationalizable (false by default) |
144 |
144 |
145 - `maxsize` : integer providing the maximum size of the string (no limit by default) |
145 - `maxsize` : integer providing the maximum size of the string (no limit by default) |
146 |
146 |
147 * optional properties for relations : |
147 * optional properties for relations : |
148 |
148 |
149 - `composite` : string indicating that the subject (composite == 'subject') |
149 - `composite` : string indicating that the subject (composite == 'subject') |
150 is composed of the objects of the relations. For the opposite case (when |
150 is composed of the objects of the relations. For the opposite case (when |
151 the object is composed of the subjects of the relation), we just set |
151 the object is composed of the subjects of the relation), we just set |
152 'object' as value. The composition implies that when the relation |
152 'object' as value. The composition implies that when the relation |
153 is deleted (so when the composite is deleted), the composed are also deleted. |
153 is deleted (so when the composite is deleted), the composed are also deleted. |
154 |
154 |
155 Contraints |
155 Contraints |
156 `````````` |
156 `````````` |
157 By default, the available constraint types are : |
157 By default, the available constraint types are : |
158 |
158 |
159 * `SizeConstraint` : allows to specify a minimum and/or maximum size on |
159 * `SizeConstraint` : allows to specify a minimum and/or maximum size on |
160 string (generic case of `maxsize`) |
160 string (generic case of `maxsize`) |
161 |
161 |
162 * `BoundConstraint` : allows to specify a minimum and/or maximum value on |
162 * `BoundConstraint` : allows to specify a minimum and/or maximum value on |
163 numeric types |
163 numeric types |
164 |
164 |
165 * `UniqueConstraint` : identical to "unique=True" |
165 * `UniqueConstraint` : identical to "unique=True" |
166 |
166 |
167 * `StaticVocabularyConstraint` : identical to "vocabulary=(...)" |
167 * `StaticVocabularyConstraint` : identical to "vocabulary=(...)" |
168 |
168 |
169 * `RQLConstraint` : allows to specify a RQL query that has to be satisfied |
169 * `RQLConstraint` : allows to specify a RQL query that has to be satisfied |
170 by the subject and/or the object of the relation. In this query the variables |
170 by the subject and/or the object of the relation. In this query the variables |
171 `S` and `O` are reserved for the entities subject and object of the |
171 `S` and `O` are reserved for the entities subject and object of the |
172 relation. |
172 relation. |
173 |
173 |
174 * `RQLVocabularyConstraint` : similar to the previous type of constraint except |
174 * `RQLVocabularyConstraint` : similar to the previous type of constraint except |
175 that it does not express a "strong" constraint, which means it is only used to |
175 that it does not express a "strong" constraint, which means it is only used to |
176 restrict the values listed in the drop-down menu of editing form, but it does |
176 restrict the values listed in the drop-down menu of editing form, but it does |
215 When a relation is not inlined and not symmetrical, and it does not require |
215 When a relation is not inlined and not symmetrical, and it does not require |
216 specific permissions, its definition (by using `SubjectRelation` and |
216 specific permissions, its definition (by using `SubjectRelation` and |
217 `ObjectRelation`) is all we need. |
217 `ObjectRelation`) is all we need. |
218 |
218 |
219 |
219 |
220 The security model |
|
221 ------------------ |
|
222 |
|
223 The security model of `cubicWeb` is based on `Access Control List`. |
|
224 The main principles are: |
|
225 |
|
226 * users and groups of users |
|
227 * a user belongs to at least one group of user |
|
228 * permissions (read, update, create, delete) |
|
229 * permissions are assigned to groups (and not to users) |
|
230 |
|
231 For `CubicWeb` in particular: |
|
232 |
|
233 * we associate rights at the enttities/relations schema level |
|
234 * for each entity, we distinguish four kind of permissions: read, |
|
235 add, update and delete |
|
236 * for each relation, we distinguish three king of permissions: read, |
|
237 add and delete (we can not modify a relation) |
|
238 * the basic groups are: Administrators, Users and Guests |
|
239 * by default, users belongs to the group Users |
|
240 * there is a virtual group called `Owners users` to which we |
|
241 can associate only deletion and update permissions |
|
242 * we can not add users to the `Owners users` group, they are |
|
243 implicetely added to it according to the context of the objects |
|
244 they own |
|
245 * the permissions of this group are only be checked on update/deletion |
|
246 actions if all the other groups the user belongs does not provide |
|
247 those permissions |
|
248 |
|
249 |
|
250 Permissions definition |
|
251 `````````````````````` |
|
252 |
|
253 Setting permissions is done with the attribute `permissions` of entities and |
|
254 relation types. It defines a dictionary where the keys are the access types |
|
255 (action), and the values are the authorized groups or expressions. |
|
256 |
|
257 For an entity type, the possible actions are `read`, `add`, `update` and |
|
258 `delete`. |
|
259 |
|
260 For a relation type, the possible actions are `read`, `add`, and `delete`. |
|
261 |
|
262 For each access type, a tuple indicates the name of the authorized groups and/or |
|
263 one or multiple RQL expressions to satisfy to grant access. The access is |
|
264 provided once the user is in the listed groups or one of the RQL condition is |
|
265 satisfied. |
|
266 |
|
267 The standard groups are : |
|
268 |
|
269 * `guests` |
|
270 |
|
271 * `users` |
|
272 |
|
273 * `managers` |
|
274 |
|
275 * `owners` : virtual group corresponding to the entity's owner. |
|
276 This can only be used for the actions `update` and `delete` of an entity |
|
277 type. |
|
278 |
|
279 It is also possible to use specific groups if they are defined in the precreate |
|
280 of the cube (``migration/precreate.py``). |
|
281 |
|
282 |
|
283 Use of RQL expression for writing rights |
|
284 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
285 It is possible to define RQL expression to provide update permission |
|
286 (`add`, `delete` and `update`) on relation and entity types. |
|
287 |
|
288 RQL expression for entity type permission : |
|
289 |
|
290 * you have to use the class `ERQLExpression` |
|
291 |
|
292 * the used expression corresponds to the WHERE statement of an RQL query |
|
293 |
|
294 * in this expression, the variables X and U are pre-defined references |
|
295 respectively on the current entity (on which the action is verified) and |
|
296 on the user who send the request |
|
297 |
|
298 * it is possible to use, in this expression, a special relation |
|
299 "has_<ACTION>_permission" where the subject is the user and the |
|
300 object is a any variable, meaning that the user needs to have |
|
301 permission to execute the action <ACTION> on the entities related |
|
302 to this variable |
|
303 |
|
304 For RQL expressions on a relation type, the principles are the same except |
|
305 for the following : |
|
306 |
|
307 * you have to use the class `RQLExpression` in the case of a non-final relation |
|
308 |
|
309 * in the expression, the variables S, O and U are pre-defined references |
|
310 to respectively the subject and the object of the current relation (on |
|
311 which the action is being verified) and the user who executed the query |
|
312 |
|
313 * we can also defined rights on attributes of an entity (non-final relation), |
|
314 knowing that : |
|
315 |
|
316 - to defines RQL expression, we have to use the class `ERQLExpression` |
|
317 in which X represents the entity the attribute belongs to |
|
318 |
|
319 - the permissions `add` and `delete` are equivalent. Only `add`/`read` |
|
320 are actually taken in consideration. |
|
321 |
|
322 In addition to that the entity type `CWPermission` from the standard library |
|
323 allow to build very complex and dynamic security architecture. The schema of |
|
324 this entity type is as follow : :: |
|
325 |
|
326 class CWPermission(MetaEntityType): |
|
327 """entity type that may be used to construct some advanced security configuration |
|
328 """ |
|
329 name = String(required=True, indexed=True, internationalizable=True, maxsize=100) |
|
330 require_group = SubjectRelation('CWGroup', cardinality='+*', |
|
331 description=_('groups to which the permission is granted')) |
|
332 require_state = SubjectRelation('State', |
|
333 description=_("entity'state in which the permission is applyable")) |
|
334 # can be used on any entity |
|
335 require_permission = ObjectRelation('**', cardinality='*1', composite='subject', |
|
336 description=_("link a permission to the entity. This " |
|
337 "permission should be used in the security " |
|
338 "definition of the entity's type to be useful.")) |
|
339 |
|
340 |
|
341 Example of configuration :: |
|
342 |
|
343 |
|
344 ... |
|
345 |
|
346 class Version(EntityType): |
|
347 """a version is defining the content of a particular project's release""" |
|
348 |
|
349 permissions = {'read': ('managers', 'users', 'guests',), |
|
350 'update': ('managers', 'logilab', 'owners',), |
|
351 'delete': ('managers', ), |
|
352 'add': ('managers', 'logilab', |
|
353 ERQLExpression('X version_of PROJ, U in_group G,' |
|
354 'PROJ require_permission P, P name "add_version",' |
|
355 'P require_group G'),)} |
|
356 |
|
357 ... |
|
358 |
|
359 class version_of(RelationType): |
|
360 """link a version to its project. A version is necessarily linked to one and only one project. |
|
361 """ |
|
362 permissions = {'read': ('managers', 'users', 'guests',), |
|
363 'delete': ('managers', ), |
|
364 'add': ('managers', 'logilab', |
|
365 RRQLExpression('O require_permission P, P name "add_version",' |
|
366 'U in_group G, P require_group G'),) |
|
367 } |
|
368 inlined = True |
|
369 |
|
370 This configuration indicates that an entity `CWPermission` named |
|
371 "add_version" can be associated to a project and provides rights to create |
|
372 new versions on this project to specific groups. It is important to notice that : |
|
373 |
|
374 * in such case, we have to protect both the entity type "Version" and the relation |
|
375 associating a version to a project ("version_of") |
|
376 |
|
377 * because of the genricity of the entity type `CWPermission`, we have to execute |
|
378 a unification with the groups and/or the states if necessary in the expression |
|
379 ("U in_group G, P require_group G" in the above example) |
|
380 |
|
381 Use of RQL expression for reading rights |
|
382 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
383 |
|
384 The principles are the same but with the following restrictions : |
|
385 |
|
386 * we can not use `RRQLExpression` on relation types for reading |
|
387 |
|
388 * special relations "has_<ACTION>_permission" can not be used |
|
389 |
|
390 |
|
391 Note on the use of RQL expression for `add` permission |
|
392 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
393 Potentially, the use of an RQL expression to add an entity or a relation |
|
394 can cause problems for the user interface, because if the expression uses |
|
395 the entity or the relation to create, then we are not able to verify the |
|
396 permissions before we actually add the entity (please note that this is |
|
397 not a problem for the RQL server at all, because the permissions checks are |
|
398 done after the creation). In such case, the permission check methods |
|
399 (check_perm, has_perm) can indicate that the user is not allowed to create |
|
400 this entity but can obtain the permission. |
|
401 To compensate this problem, it is usually necessary, for such case, |
|
402 to use an action that reflects the schema permissions but which enables |
|
403 to check properly the permissions so that it would show up if necessary. |
|
404 |
|
405 |
|
406 Updating your application with your new schema |
220 Updating your application with your new schema |
407 `````````````````````````````````````````````` |
221 ---------------------------------------------- |
408 |
222 |
409 If you modified your schema, the update is not automatic; indeed, this is |
223 If you modified your schema, the update is not automatic; indeed, this is |
410 in general not a good idea. |
224 in general not a good idea. |
411 Instead, you call a shell on your application, which is a |
225 Instead, you call a shell on your application, which is a |
412 an interactive python shell, with an appropriate |
226 an interactive python shell, with an appropriate |
413 cubicweb environment :: |
227 cubicweb environment :: |
414 |
228 |
415 cubicweb-ctl shell myinstance |
229 cubicweb-ctl shell myinstance |
416 |
230 |