9 in cubes. The schema for a cube is defined in a :file:schema.py file or in |
9 in cubes. The schema for a cube is defined in a :file:schema.py file or in |
10 one or more Python files under the :file:`schema` directory (python package). |
10 one or more Python files under the :file:`schema` directory (python package). |
11 |
11 |
12 At this point, it is important to make clear the difference between |
12 At this point, it is important to make clear the difference between |
13 *relation type* and *relation definition*: a *relation type* is only a relation |
13 *relation type* and *relation definition*: a *relation type* is only a relation |
14 name with potentially other additionnal properties (see below), whereas a |
14 name with potentially other additional properties (see below), whereas a |
15 *relation definition* is a complete triplet |
15 *relation definition* is a complete triplet |
16 "<subject entity type> <relation type> <object entity type>". |
16 "<subject entity type> <relation type> <object entity type>". |
17 A relation type could have been implied if none is related to a |
17 |
18 relation definition of the schema. |
18 Also, it should be clear that to properly handle data migration, an |
19 |
19 instance's schema |
20 Also, it should be clear that to properly handle data migration, an instance'schema |
20 is stored in the database, so the python schema file used to defined it is only read |
21 is stored in the database, so the python schema file used to defined it are only readen |
|
22 when the instance is created or upgraded. |
21 when the instance is created or upgraded. |
23 |
22 |
24 The following built-in types are available : `String`, `Int`, `Float`, |
23 The following built-in types are available: `String`, `Int`, `Float`, |
25 `Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` |
24 `Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` |
26 and `Password`. |
25 and `Password`. |
27 |
26 |
28 You'll also have access to :ref:`base cubicweb entity types <CWBaseEntityTypes>`. |
27 You'll also have access to :ref:`base CubicWeb entity types <CWBaseEntityTypes>`. |
29 |
28 |
30 The instance schema is accessible through the .schema attribute of the |
29 The instance schema is accessible through the .schema attribute of the |
31 `vregistry`. It's an instance of :class:`cubicweb.schema.Schema`, which |
30 `vregistry`. It's an instance of :class:`cubicweb.schema.Schema`, which |
32 extends :class:`yams.schema.Schema`. |
31 extends :class:`yams.schema.Schema`. |
33 |
32 |
34 :note: |
33 :note: |
35 In previous yams versions, almost all classes where available without |
34 In previous yams versions, almost all classes where available without |
36 any import, but the should now be explicitely imported. |
35 any import, but the should now be explicitly imported. |
37 |
36 |
38 |
37 |
39 Entity type |
38 Entity type |
40 ~~~~~~~~~~~ |
39 ~~~~~~~~~~~ |
41 It's an instance of :class:`yams.schema.EntitySchema`. Each entity types has |
40 An entity type is an instance of :class:`yams.schema.EntitySchema`. Each entity type has |
42 a set of attributes and relation and some permissions, defining who can add, read, |
41 a set of attributes and relations, and some permissions which define who can add, read, |
43 update or delete entities of this type. |
42 update or delete entities of this type. |
44 |
43 |
45 XXX yams inheritance |
44 XXX yams inheritance |
46 |
45 |
47 Relation type |
46 Relation type |
48 ~~~~~~~~~~~~~ |
47 ~~~~~~~~~~~~~ |
49 It's an instance of :class:`yams.schema.RelationSchema`. A relation type is simply |
48 A relation type is an instance of :class:`yams.schema.RelationSchema`. A relation type is simply |
50 a semantic definition of a kind of relationship that may occurs in your application. |
49 a semantic definition of a kind of relationship that may occur in an application. |
51 |
50 |
52 It's important to choose a good name, at least to avoid conflicts with some semantically |
51 It is important to choose a good name, at least to avoid conflicts with some semantically |
53 different relation defined in other cubes (since we've no namespace yet). |
52 different relation defined in other cubes (since we've no name space yet). |
54 |
53 |
55 A relation type hold the following properties (which are hence shared between all |
54 A relation type holds the following properties (which are hence shared between all |
56 relation definitions of that type): |
55 relation definitions of that type): |
57 |
56 |
58 * `inlined` : boolean handling the physical optimization for archiving |
57 * `inlined`: boolean handling the physical optimization for archiving |
59 the relation in the subject entity table, instead of creating a specific |
58 the relation in the subject entity table, instead of creating a specific |
60 table for the relation. This applies to relations where cardinality |
59 table for the relation. This applies to relations where cardinality |
61 of subject->relation->object is 0..1 (`?`) or 1..1 (`1`) for *all* its relation |
60 of subject->relation->object is 0..1 (`?`) or 1..1 (`1`) for *all* its relation |
62 definitions. |
61 definitions. |
63 |
62 |
64 * `symmetric` : boolean indicating that the relation is symmetrical, which |
63 * `symmetric`: boolean indicating that the relation is symmetrical, which |
65 means that `X relation Y` implies `Y relation X`. |
64 means that `X relation Y` implies `Y relation X`. |
66 |
65 |
67 |
66 |
68 Relation definition |
67 Relation definition |
69 ~~~~~~~~~~~~~~~~~~~ |
68 ~~~~~~~~~~~~~~~~~~~ |
70 It's an instance of :class:`yams.schema.RelationDefinition`. It is a complete triplet |
69 A relation definition is an instance of :class:`yams.schema.RelationDefinition`. It is a complete triplet |
71 "<subject entity type> <relation type> <object entity type>". |
70 "<subject entity type> <relation type> <object entity type>". |
|
71 |
|
72 When creating a new instance of that class, the corresponding |
|
73 :class:`RelationType` instance is created on the fly if necessary. |
|
74 |
72 |
75 |
73 Properties |
76 Properties |
74 `````````` |
77 `````````` |
75 |
78 |
76 * Optional properties for attributes and relations : |
79 * Optional properties for attributes and relations: |
77 |
80 |
78 - `description` : a string describing an attribute or a relation. By default |
81 - `description`: a string describing an attribute or a relation. By default |
79 this string will be used in the editing form of the entity, which means |
82 this string will be used in the editing form of the entity, which means |
80 that it is supposed to help the end-user and should be flagged by the |
83 that it is supposed to help the end-user and should be flagged by the |
81 function `_` to be properly internationalized. |
84 function `_` to be properly internationalized. |
82 |
85 |
83 - `constraints` : a list of conditions/constraints that the relation has to |
86 - `constraints`: a list of conditions/constraints that the relation has to |
84 satisfy (c.f. `Constraints`_) |
87 satisfy (c.f. `Constraints`_) |
85 |
88 |
86 - `cardinality` : a two character string which specify the cardinality of the |
89 - `cardinality`: a two character string specifying the cardinality of the |
87 relation. The first character defines the cardinality of the relation on |
90 relation. The first character defines the cardinality of the relation on |
88 the subject, and the second on the object. When a relation can have |
91 the subject, and the second on the object. When a relation can have |
89 multiple subjects or objects, the cardinality applies to all, |
92 multiple subjects or objects, the cardinality applies to all, |
90 not on a one-to-one basis (so it must be consistent...). The possible |
93 not on a one-to-one basis (so it must be consistent...). The possible |
91 values are inspired from regular expression syntax : |
94 values are inspired from regular expression syntax: |
92 |
95 |
93 * `1`: 1..1 |
96 * `1`: 1..1 |
94 * `?`: 0..1 |
97 * `?`: 0..1 |
95 * `+`: 1..n |
98 * `+`: 1..n |
96 * `*`: 0..n |
99 * `*`: 0..n |
97 |
100 |
98 * optional properties for attributes : |
101 * optional properties for attributes: |
99 |
102 |
100 - `unique` : boolean indicating if the value of the attribute has to be unique |
103 - `unique`: boolean indicating if the value of the attribute has to be unique |
101 or not within all entities of the same type (false by default) |
104 or not within all entities of the same type (false by default) |
102 |
105 |
103 - `indexed` : boolean indicating if an index needs to be created for this |
106 - `indexed`: boolean indicating if an index needs to be created for this |
104 attribute in the database (false by default). This is useful only if |
107 attribute in the database (false by default). This is useful only if |
105 you know that you will have to run numerous searches on the value of this |
108 you know that you will have to run numerous searches on the value of this |
106 attribute. |
109 attribute. |
107 |
110 |
108 - `default` : default value of the attribute. In case of date types, the values |
111 - `default`: default value of the attribute. In case of date types, the values |
109 which could be used correspond to the RQL keywords `TODAY` and `NOW`. |
112 which could be used correspond to the RQL keywords `TODAY` and `NOW`. |
110 |
113 |
111 * optional properties of type `String` : |
114 * optional properties for type `String` attributes: |
112 |
115 |
113 - `fulltextindexed` : boolean indicating if the attribute is part of |
116 - `fulltextindexed`: boolean indicating if the attribute is part of |
114 the full text index (false by default) (*applicable on the type `Byte` |
117 the full text index (false by default) (*applicable on the type `Byte` |
115 as well*) |
118 as well*) |
116 |
119 |
117 - `internationalizable` : boolean indicating if the value of the attribute |
120 - `internationalizable`: boolean indicating if the value of the attribute |
118 is internationalizable (false by default) |
121 is internationalizable (false by default) |
119 |
122 |
120 * optional properties for relations : |
123 * optional properties for relations: |
121 |
124 |
122 - `composite` : string indicating that the subject (composite == 'subject') |
125 - `composite`: string indicating that the subject (composite == 'subject') |
123 is composed of the objects of the relations. For the opposite case (when |
126 is composed of the objects of the relations. For the opposite case (when |
124 the object is composed of the subjects of the relation), we just set |
127 the object is composed of the subjects of the relation), we just set |
125 'object' as value. The composition implies that when the relation |
128 'object' as value. The composition implies that when the relation |
126 is deleted (so when the composite is deleted, at least), the composed are also deleted. |
129 is deleted (so when the composite is deleted, at least), the composed are also deleted. |
127 |
130 |
128 - `fti_container`: XXX feed me |
131 - `fulltext_container`: string indicating if the value if the full text |
|
132 indexation of the entity on one end of the relation should be used |
|
133 to find the entity on the other end. The possible values are |
|
134 'subject' or 'object'. For instance the use_email relation has |
|
135 that property set to 'subject', since when performing a full text |
|
136 search people want to find the entity using an email address, and not |
|
137 the entity representing the email address. |
129 |
138 |
130 Constraints |
139 Constraints |
131 ``````````` |
140 ``````````` |
132 |
141 |
133 By default, the available constraint types are : |
142 By default, the available constraint types are: |
134 |
143 |
135 General Constraints |
144 General Constraints |
136 ...................... |
145 ...................... |
137 |
146 |
138 * `SizeConstraint` : allows to specify a minimum and/or maximum size on |
147 * `SizeConstraint`: allows to specify a minimum and/or maximum size on |
139 string (generic case of `maxsize`) |
148 string (generic case of `maxsize`) |
140 |
149 |
141 * `BoundConstraint` : allows to specify a minimum and/or maximum value on |
150 * `BoundConstraint`: allows to specify a minimum and/or maximum value on |
142 numeric types |
151 numeric types |
143 |
152 |
144 * `UniqueConstraint` : identical to "unique=True" |
153 * `UniqueConstraint`: identical to "unique=True" |
145 |
154 |
146 * `StaticVocabularyConstraint` : identical to "vocabulary=(...)" |
155 * `StaticVocabularyConstraint`: identical to "vocabulary=(...)" |
147 |
156 |
148 XXX Attribute, TODAY, NOW |
157 XXX Attribute, TODAY, NOW |
149 |
158 |
150 RQL Based Constraints |
159 RQL Based Constraints |
151 ...................... |
160 ...................... |
157 specified using ``mainvars``. The argument expects a single string with all |
166 specified using ``mainvars``. The argument expects a single string with all |
158 variable's name separated by spaces. The last one, ``msg``, is the error message |
167 variable's name separated by spaces. The last one, ``msg``, is the error message |
159 displayed when the constraint fails. As RQLVocabularyConstraint never fails the |
168 displayed when the constraint fails. As RQLVocabularyConstraint never fails the |
160 third argument is not available. |
169 third argument is not available. |
161 |
170 |
162 * `RQLConstraint` : allows to specify a RQL query that has to be satisfied |
171 * `RQLConstraint`: allows to specify a RQL query that has to be satisfied |
163 by the subject and/or the object of relation. In this query the variables |
172 by the subject and/or the object of relation. In this query the variables |
164 `S` and `O` are reserved for the entities subject and object of the |
173 `S` and `O` are reserved for the relation subject and object entities. |
165 relation. |
174 |
166 |
175 * `RQLVocabularyConstraint`: similar to the previous type of constraint except |
167 * `RQLVocabularyConstraint` : similar to the previous type of constraint except |
|
168 that it does not express a "strong" constraint, which means it is only used to |
176 that it does not express a "strong" constraint, which means it is only used to |
169 restrict the values listed in the drop-down menu of editing form, but it does |
177 restrict the values listed in the drop-down menu of editing form, but it does |
170 not prevent another entity to be selected. |
178 not prevent another entity to be selected. |
171 |
179 |
172 * `RQLUniqueConstraint` : allows to the specify a RQL query that ensure that an |
180 * `RQLUniqueConstraint`: allows to the specify a RQL query that ensure that an |
173 attribute is unique in a specific context. The Query must **never** return more |
181 attribute is unique in a specific context. The Query must **never** return more |
174 than a single result to be satisfied. In this query the variables `S` is |
182 than a single result to be satisfied. In this query the variables `S` is |
175 reserved for the entity subject of the relation. The other variable should be |
183 reserved for the relation subject entity. The other variables should be |
176 specified with the second constructor argument (mainvars). This constraints |
184 specified with the second constructor argument (mainvars). This constraints |
177 should be used when UniqueConstraint doesn't fit. Here is a simple example :: |
185 should be used when UniqueConstraint doesn't fit. Here is a simple example :: |
178 |
186 |
179 # Check that in the same Workflow each state's name is unique. Using |
187 # Check that in the same Workflow each state's name is unique. Using |
180 # UniqueConstraint (or unique=True) here would prevent states in different |
188 # UniqueConstraint (or unique=True) here would prevent states in different |
186 mainvars='Y', |
194 mainvars='Y', |
187 msg=_('workflow already have a state of that name')) |
195 msg=_('workflow already have a state of that name')) |
188 |
196 |
189 |
197 |
190 |
198 |
191 * `RQLUniqueConstraint` : allows to the specify a RQL query that ensure that an |
|
192 attribute is unique in a specific context. The Query must **never** return more |
|
193 than a single result to be satisfied. In this query the variables `S` is |
|
194 reserved for the entity subject of the relation. The other variable should be |
|
195 specified with the second constructor argument (mainvars). This constraints |
|
196 should be used when UniqueConstraint doesn't fit. Here is a simple example :: |
|
197 |
|
198 # Check that in the same Workflow each state's name is unique. Using |
|
199 # UniqueConstraint (or unique=True) here would prevent states in different |
|
200 # workflows to have the same name. |
|
201 |
|
202 # With: State S, Workflow W, String N ; S state_of W, S name N |
|
203 |
|
204 RQLUniqueConstraint('S name N, S state_of WF, Y state_of WF, Y name N', |
|
205 mainvars='Y', |
|
206 msg=_('workflow already have a state of that name')) |
|
207 |
|
208 |
|
209 |
|
210 XXX note about how to add new constraint |
199 XXX note about how to add new constraint |
211 |
200 |
212 .. _securitymodel: |
201 .. _securitymodel: |
213 |
202 |
214 |
203 |
215 The security model |
204 The security model |
216 ~~~~~~~~~~~~~~~~~~ |
205 ~~~~~~~~~~~~~~~~~~ |
217 |
206 |
218 The security model of `cubicWeb` is based on `Access Control List`. |
207 The security model of `CubicWeb` is based on `Access Control List`. |
219 The main principles are: |
208 The main principles are: |
220 |
209 |
221 * users and groups of users |
210 * users and groups of users |
222 * a user belongs to at least one group of user |
211 * a user belongs to at least one group of user |
223 * permissions (read, update, create, delete) |
212 * permissions (read, update, create, delete) |
224 * permissions are assigned to groups (and not to users) |
213 * permissions are assigned to groups (and not to users) |
225 |
214 |
226 For *CubicWeb* in particular: |
215 For *CubicWeb* in particular: |
227 |
216 |
228 * we associate rights at the enttities/relations schema level |
217 * we associate rights at the entities/relations schema level |
229 * for each entity, we distinguish four kind of permissions: read, |
218 * for each entity, we distinguish four kinds of permissions: `read`, |
230 add, update and delete |
219 `add`, `update` and `delete` |
231 * for each relation, we distinguish three kinds of permissions: read, |
220 * for each relation, we distinguish three kinds of permissions: `read`, |
232 add and delete (we can not modify a relation) |
221 `add` and `delete` (it is not possible to `modify` a relation) |
233 * the basic groups are: Administrators, Users and Guests |
222 * the default groups are: `administrators`, `users` and `guests` |
234 * by default, users belong to the group Users |
223 * by default, users belong to the `users` group |
235 * there is a virtual group called `Owners` to which we |
224 * there is a virtual group called `owners` to which we |
236 can associate only deletion and update permissions |
225 can associate only `delete` and `update` permissions |
237 * we can not add users to the `Owners` group, they are |
226 |
238 implicitly added to it according to the context of the objects |
227 * we can not add users to the `Owners` group, they are |
239 they own |
228 implicitly added to it according to the context of the objects |
240 * the permissions of this group are only checked on update/deletion |
229 they own |
241 actions if all the other groups the user belongs to does not provide |
230 * the permissions of this group are only checked on `update`/`delete` |
242 those permissions |
231 actions if all the other groups the user belongs to do not provide |
|
232 those permissions |
243 |
233 |
244 Setting permissions is done with the attribute `__permissions__` of entities and |
234 Setting permissions is done with the attribute `__permissions__` of entities and |
245 relation types. It defines a dictionary where the keys are the access types |
235 relation types. The value of this attribute is a dictionary where the keys are the access types |
246 (action), and the values are the authorized groups or expressions. |
236 (action), and the values are the authorized groups or expressions. |
247 |
237 |
248 For an entity type, the possible actions are `read`, `add`, `update` and |
238 For an entity type, the possible actions are `read`, `add`, `update` and |
249 `delete`. |
239 `delete`. |
250 |
240 |
251 For a relation type, the possible actions are `read`, `add`, and `delete`. |
241 For a relation type, the possible actions are `read`, `add`, and `delete`. |
252 |
242 |
253 For each access type, a tuple indicates the name of the authorized groups and/or |
243 For each access type, a tuple indicates the name of the authorized groups and/or |
254 one or multiple RQL expressions to satisfy to grant access. The access is |
244 one or multiple RQL expressions to satisfy to grant access. The access is |
255 provided if the user is in one of the listed groups or one of if the RQL condition |
245 provided if the user is in one of the listed groups or if one of the RQL condition |
256 is satisfied. |
246 is satisfied. |
257 |
247 |
258 The standard user groups |
248 The standard user groups |
259 ```````````````````````` |
249 ```````````````````````` |
260 |
250 |
262 |
252 |
263 * `users` |
253 * `users` |
264 |
254 |
265 * `managers` |
255 * `managers` |
266 |
256 |
267 * `owners` : virtual group corresponding to the entity's owner. |
257 * `owners`: virtual group corresponding to the entity's owner. |
268 This can only be used for the actions `update` and `delete` of an entity |
258 This can only be used for the actions `update` and `delete` of an entity |
269 type. |
259 type. |
270 |
260 |
271 It is also possible to use specific groups if they are defined in the |
261 It is also possible to use specific groups if they are defined in the |
272 precreate of the cube (``migration/precreate.py``). Defining groups in |
262 precreate script of the cube (``migration/precreate.py``). Defining groups in |
273 postcreate or even later makes them NOT available for security |
263 postcreate script or later makes them unavailable for security |
274 purposes (in this case, an `sync_schema_props_perms` command have to |
264 purposes (in this case, an `sync_schema_props_perms` command has to |
275 be issued in a CubicWeb shell). |
265 be issued in a CubicWeb shell). |
276 |
266 |
277 |
267 |
278 Use of RQL expression for write permissions |
268 Use of RQL expression for write permissions |
279 ``````````````````````````````````````````` |
269 ``````````````````````````````````````````` |
280 It is possible to define RQL expression to provide update permission |
270 It is possible to define RQL expression to provide update permission |
281 (`add`, `delete` and `update`) on relation and entity types. |
271 (`add`, `delete` and `update`) on relation and entity types. |
282 |
272 |
283 RQL expression for entity type permission : |
273 RQL expression for entity type permission: |
284 |
274 |
285 * you have to use the class `ERQLExpression` |
275 * you have to use the class `ERQLExpression` |
286 |
276 |
287 * the used expression corresponds to the WHERE statement of an RQL query |
277 * the used expression corresponds to the WHERE statement of an RQL query |
288 |
278 |
289 * in this expression, the variables X and U are pre-defined references |
279 * in this expression, the variables `X` and `U` are pre-defined references |
290 respectively on the current entity (on which the action is verified) and |
280 respectively on the current entity (on which the action is verified) and |
291 on the user who send the request |
281 on the user who send the request |
292 |
282 |
293 * it is possible to use, in this expression, a special relation |
283 * it is possible to use, in this expression, a special relation |
294 "has_<ACTION>_permission" where the subject is the user and the |
284 "has_<ACTION>_permission" where the subject is the user and the |
295 object is any variable, meaning that the user needs to have |
285 object is any variable, meaning that the user needs to have |
296 permission to execute the action <ACTION> on the entities related |
286 permission to execute the action <ACTION> on the entities related |
297 to this variable |
287 to this variable |
298 |
288 |
299 For RQL expressions on a relation type, the principles are the same except |
289 For RQL expressions on a relation type, the principles are the same except |
300 for the following : |
290 for the following: |
301 |
291 |
302 * you have to use the class `RRQLExpression` in the case of a non-final relation |
292 * you have to use the class `RRQLExpression` in the case of a non-final relation |
303 |
293 |
304 * in the expression, the variables S, O and U are pre-defined references |
294 * in the expression, the variables `S`, `O` and `U` are pre-defined references |
305 to respectively the subject and the object of the current relation (on |
295 to respectively the subject and the object of the current relation (on |
306 which the action is being verified) and the user who executed the query |
296 which the action is being verified) and the user who executed the query |
307 |
297 |
308 * we can also define rights over attributes of an entity (non-final relation), |
298 * we can also define rights over attributes of an entity (non-final relation), |
309 knowing that : |
299 knowing that: |
310 |
300 |
311 - to define RQL expression, we have to use the class `ERQLExpression` |
301 - to define RQL expression, we have to use the class `ERQLExpression` |
312 in which X represents the entity the attribute belongs to |
302 in which `X` represents the entity the attribute belongs to |
313 |
303 |
314 - the permissions `add` and `delete` are equivalent. Only `add`/`read` |
304 - the permissions `add` and `delete` are equivalent. Only `add`/`read` |
315 are actually taken in consideration. |
305 are actually taken in consideration. |
316 |
306 |
317 :Note on the use of RQL expression for `add` permission: |
307 :Note on the use of RQL expression for `add` permission: |
380 The entity described above defines three attributes of type String, |
379 The entity described above defines three attributes of type String, |
381 last_name, first_name and title, an attribute of type Date for the date of |
380 last_name, first_name and title, an attribute of type Date for the date of |
382 birth and a relation that connects a `Person` to another entity of type |
381 birth and a relation that connects a `Person` to another entity of type |
383 `Company` through the semantic `works_for`. |
382 `Company` through the semantic `works_for`. |
384 |
383 |
|
384 :Naming convention: |
|
385 |
|
386 Entity class names must start with an uppercase letter. The common |
|
387 usage is to use ``CamelCase`` names. |
|
388 |
|
389 Attribute and relation names must start with a lowercase letter. The |
|
390 common usage is to use ``underscore_separated_words``. Attribute and |
|
391 relation names starting with a single underscore are permitted, to |
|
392 denote a somewhat "protected" or "private" attribute. |
|
393 |
|
394 In any case, identifiers starting with "CW" or "cw" are reserved for |
|
395 internal use by the framework. |
|
396 |
|
397 |
385 The name of the Python attribute corresponds to the name of the attribute |
398 The name of the Python attribute corresponds to the name of the attribute |
386 or the relation in *CubicWeb* application. |
399 or the relation in *CubicWeb* application. |
387 |
400 |
388 An attribute is defined in the schema as follows:: |
401 An attribute is defined in the schema as follows:: |
389 |
402 |
390 attr_name = attr_type(properties) |
403 attr_name = attr_type(properties) |
391 |
404 |
392 where `attr_type` is one of the type listed above and `properties` is |
405 where `attr_type` is one of the type listed above and `properties` is |
393 a list of the attribute needs to statisfy (see `Properties`_ |
406 a list of the attribute needs to satisfy (see `Properties`_ |
394 for more details). |
407 for more details). |
395 |
|
396 |
|
397 * relations can be defined by using `ObjectRelation` or `SubjectRelation`. |
|
398 The first argument of `SubjectRelation` or `ObjectRelation` gives respectively |
|
399 the object/subject entity type of the relation. This could be : |
|
400 |
|
401 * a string corresponding to an entity type |
|
402 |
|
403 * a tuple of string corresponding to multiple entity types |
|
404 |
|
405 * special string such as follows : |
|
406 |
|
407 - "**" : all types of entities |
|
408 - "*" : all types of non-meta entities |
|
409 - "@" : all types of meta entities but not system entities (e.g. used for |
|
410 the basic schema description) |
|
411 |
408 |
412 * it is possible to use the attribute `meta` to flag an entity type as a `meta` |
409 * it is possible to use the attribute `meta` to flag an entity type as a `meta` |
413 (e.g. used to describe/categorize other entities) |
410 (e.g. used to describe/categorize other entities) |
414 |
411 |
415 *Note* : if you end up with an `if` in the definition of your entity, this probably |
412 .. XXX the paragraph below needs clarification and / or moving out in |
|
413 .. another place |
|
414 |
|
415 *Note*: if you end up with an `if` in the definition of your entity, this probably |
416 means that you need two separate entities that implement the `ITree` interface and |
416 means that you need two separate entities that implement the `ITree` interface and |
417 get the result from `.children()` which ever entity is concerned. |
417 get the result from `.children()` which ever entity is concerned. |
418 |
418 |
419 Inheritance |
419 Inheritance |
420 ``````````` |
420 ``````````` |
438 inlined = True |
438 inlined = True |
439 cardinality = '?*' |
439 cardinality = '?*' |
440 subject = '*' |
440 subject = '*' |
441 object = 'CWUser' |
441 object = 'CWUser' |
442 |
442 |
443 In the case of simultaneous relations definitions, `subject` and `object` |
443 If provided, the `subject` and `object` attributes denote the subject |
444 can both be equal to the value of the first argument of `SubjectRelation` |
444 and object of the various relation definitions related to the relation |
445 and `ObjectRelation`. |
445 type. Allowed values for these attributes are: |
|
446 |
|
447 * a string corresponding to an entity type |
|
448 * a tuple of string corresponding to multiple entity types |
|
449 * special string such as follows: |
|
450 |
|
451 - "**": all types of entities |
|
452 - "*": all types of non-meta entities |
|
453 - "@": all types of meta entities but not system entities (e.g. used for |
|
454 the basic schema description) |
446 |
455 |
447 When a relation is not inlined and not symmetrical, and it does not require |
456 When a relation is not inlined and not symmetrical, and it does not require |
448 specific permissions, its definition (by using `SubjectRelation` and |
457 specific permissions, it can be defined using a `SubjectRelation` |
449 `ObjectRelation`) is all we need. |
458 attribute in the EntityType class. The first argument of `SubjectRelation` gives |
450 |
459 the entity type for the object of the relation. |
|
460 |
|
461 :Naming convention: |
|
462 |
|
463 Although this way of defining relations uses a Python class, the |
|
464 naming convention defined earlier prevails over the PEP8 conventions |
|
465 used in the framework: relation type class names use |
|
466 ``underscore_separated_words``. |
|
467 |
|
468 :Historical note: |
|
469 |
|
470 It has been historically possible to use `ObjectRelation` which |
|
471 defines a relation in the opposite direction. This feature is soon to be |
|
472 deprecated and therefore should not be used in newly written code. |
|
473 |
|
474 :Future deprecation note: |
|
475 |
|
476 In an even more remote future, it is quite possible that the |
|
477 SubjectRelation shortcut will become deprecated, in favor of the |
|
478 RelationType declaration which offers some advantages in the context |
|
479 of reusable cubes. |
451 |
480 |
452 Definition of permissions |
481 Definition of permissions |
453 ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
482 ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
454 The entity type `CWPermission` from the standard library |
483 The entity type `CWPermission` from the standard library |
455 allows to build very complex and dynamic security architectures. The schema of |
484 allows to build very complex and dynamic security architectures. The schema of |
456 this entity type is as follow : |
485 this entity type is as follow: |
457 |
486 |
458 .. sourcecode:: python |
487 .. sourcecode:: python |
459 |
488 |
460 class CWPermission(EntityType): |
489 class CWPermission(EntityType): |
461 """entity type that may be used to construct some advanced security configuration |
490 """entity type that may be used to construct some advanced security configuration |
462 """ |
491 """ |
463 name = String(required=True, indexed=True, internationalizable=True, maxsize=100) |
492 name = String(required=True, indexed=True, internationalizable=True, maxsize=100) |
464 require_group = SubjectRelation('CWGroup', cardinality='+*', |
493 require_group = SubjectRelation('CWGroup', cardinality='+*', |
465 description=_('groups to which the permission is granted')) |
494 description=_('groups to which the permission is granted')) |
466 require_state = SubjectRelation('State', |
495 require_state = SubjectRelation('State', |
467 description=_("entity's state in which the permission is applicable")) |
496 description=_("entity's state in which the permission is applicable")) |
468 # can be used on any entity |
497 # can be used on any entity |
469 require_permission = ObjectRelation('**', cardinality='*1', composite='subject', |
498 require_permission = ObjectRelation('**', cardinality='*1', composite='subject', |
470 description=_("link a permission to the entity. This " |
499 description=_("link a permission to the entity. This " |
471 "permission should be used in the security " |
500 "permission should be used in the security " |
472 "definition of the entity's type to be useful.")) |
501 "definition of the entity's type to be useful.")) |
473 |
502 |
474 |
503 |