Commit 21d55e07 authored by Nicolas Chauvat's avatar Nicolas Chauvat
Browse files

[doc] divided book in parts

parent 80c65c9f7c41
.. -*- coding: utf-8 -*-
Data Model definition (*schema*)
================================
The schema is the main concept of `LAX` applications as it defines the
data model we will handle. It is based on entities types already defined
in the library and others, more specific, we would expect to find in one or
more Python files under the `schema` directory.
It is important to make clear the difference between relation type and relation
definition: a relation type is only a relation name with potentially other
additionnal properties (see XXXX), whereas a relation definition is a complete
triplet "<subject entity type> <relation type> <object entity type>". A relation
type could have been implied if none is related to a relation definition of the
schema.
.. include:: 03-10-stdlib-schemas.en.txt
.. include:: 03-11-definition-schema.en.txt
.. -*- coding: utf-8 -*-
Pre-defined schemas in the library
----------------------------------
The library defines a set of entities schemas that are required by the system
or commonly used in `LAX` applications.
Of course, you can extend those schemas if necessarry.
System schemas
``````````````
Those are defined in::
./myapp/ginco/schemas/
./myapp/ginco/entities/
``schemas/`` defines the data model you will use in your application.
It allows you to describre the entities and the relations you will need.
``entities/`` deifnes the methods you might need on the entities you
defined in your schema.
The system entities available are:
* `EUser`, system users
* `EGroup`, users groups
* `EEType`, entity type
* `ERType`, relation type
* `State`, workflow state
* `Transition`, workflow transition
* `TrInfo`, record of a transition trafic for an entity
* `EmailAddress`, email address, used by the system to send notifications
to the users and also used by others optionnals schemas
* `EProperty`, used to configure the application
* `EPermission`, used to configure the security of the application
* `Card`, generic documenting card
* `Bookmark`, an entity type used to allow a user to customize his links within
the application
Components in the library
`````````````````````````
Those are defined in::
./myapp/ginco-apps/
An application is based on several basic components. In the set of available
basic components we can find by example:
* `ecomment`, provides an entity type for `Comment` allowing us to comment others
site's entities
* `emailinglist`, provides an entity type for `Mailinglist` which groups informations
in a discussion list
* `efile`, provides entity types for `File` et `Image` used to represent
files (text or binary) with additionnal informations such as MIME type or
encoding.
* `elink`, provides an entity type for hypertext link (`Link`)
* `eblog`, provides an entity type weblog (`Blog`)
* `eperson`, provides an entity type for a person (`Person`)
* `eaddressbook`, provides an entity type used to represent phone
numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
* `eclasstags`, categorization system based on tags (`Tag`)
* `eclassfolders`, categorization system based on folders hierarchy in order
to create navigation sections (`Folder`)
* `eemail`, archiving management for emails (`Email`, `Emailpart`,
`Emailthread`)
* `ebasket`, basket management (`Basket`) allowing to group entities
To declare the use of a component, once installed, add the name of the component
to the variable `__use__` in the file `__pkginfo__.py` of your own component.
.. -*- coding: utf-8 -*-
Entity type definition
----------------------
An entity type is defined by a Python class which inherits `EntityType`. The
class name correponds to the type name. Then the content of the class contains
the description of attributes and relations for the defined entity type,
by example ::
class Personne(EntityType):
"""A person with the properties and the relations necessarry for my
application"""
last_name = String(required=True, fulltextindexed=True)
first_name = String(required=True, fulltextindexed=True)
title = String(vocabulary=('M', 'Mme', 'Mlle'))
date_of_birth = Date()
works_for = SubjectRelation('Company', cardinality='?*')
* the name of the Python attribute corresponds to the name of the attribute
or the relation in `LAX` application.
* all built-in types are available: `String`, `Int`, `Float`,
`Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
* each entity has at least the following meta-relations:
- `eid` (`Int`)
- `creation_date` (`Datetime`)
- `modification_date` (`Datetime`)
- `created_by` (`EUser`) (which user created the entity)
- `owned_by` (`EUser`) (who does the entity belongs to, by default the
creator but not necessarry and it could have multiple owners)
- `is` (`EEType`)
* it is also possible to define relations of type object by using `ObjectRelation`
instead of `SubjectRelation`
* the first argument of `SubjectRelation` and `ObjectRelation` gives respectively
the object/subject entity type of the relation. This could be:
* a string corresponding to an entity type
* a tuple of string correponding to multiple entities types
* special string such as follows:
- "**" : all types of entities
- "*" : all types of entities non meta
- "@" : all types of meta entities but not system entities (e.g. used for
the basis schema description)
* it is possible to use the attribute `meta` to flag an entity type as a `meta`
(e.g. used to describe/categorize other entities)
* optional properties for attributes and relations:
- `description` : string describing an attribute or a relation. By default
this string will be used in the editing form of the entity, which means
that it is supposed to help the end-user and should be flagged by the
function `_` to be properly internationalized.
- `constraints` : list of conditions/constraints that the relation needs to
satisfy (c.f. `Contraints`_)
- `cardinality` : two characters string which specify the cardinality of the
relation. The first character defines the cardinality of the relation on
the subject, the second on the object of the relation. When a relation
has multiple possible subjects or objects, the cardinality applies to all
and not on a one to one basis (so it must be consistent...). The possible
values are inspired from regular expressions syntax:
* `1`: 1..1
* `?`: 0..1
* `+`: 1..n
* `*`: 0..n
- `meta` : boolean indicating that the relation is a meta-relation (false by
default)
* optionnal properties for attributes:
- `required` : boolean indicating if the attribute is required (false by default)
- `unique` : boolean indicating if the value of the attribute has to be unique
or not within all entities of the same type (false by default)
- `indexed` : boolean indicating if an index needs to be created for this
attribute in the database (false by default). This is usefull only if
you know that you will have to run numerous searches on the value of this
attribute.
- `default` : default value of the attribute. In case of date types, the values
which could be used correpond to the RQL keywords `TODAY` and `NOW`.
- `vocabulary` : specify static possible values of an attribute
* optionnal properties of type `String`:
- `fulltextindexed` : boolean indicating if the attribute is part of
the full text index (false by default) (*applicable on the type `Byte`
as well*)
- `internationalizable` : boolean indicating if the value of the attribute
is internationalizable (false by default)
- `maxsize` : integer providing the maximum size of the string (no limit by default)
* optionnal properties for relations:
- `composite` : string indicating that the subject (composite == 'subject')
is composed of the objects of the relations. For the opposite case (when
the object is composed of the subjects of the relation), we just need
to set 'object' as the value. The composition implies that when the relation
is deleted (so when the composite is deleted), the composed are also deleted.
[PAS CLAIR]
Contraints
``````````
By default, the available constraints types are:
* `SizeConstraint` : allows to specify a minimum and/or maximum size on
string (generic case of `maxsize`)
* `BoundConstraint` : allows to specify a minimum and/or maximum value on
numeric types
* `UniqueConstraint` : identical to "unique=True"
* `StaticVocabularyConstraint` : identical to "vocabulary=(...)"
* `RQLConstraint` : allows to specify a RQL query that needs to be satisfied
by the subject and/or the object of the relation. In this query the variables
`S` and `O` are reserved for the entities subject and object of the
relation.
* `RQLVocabularyConstraint` : similar to the previous type of constraint except
that it does not express a "strong" constraint, which means it is only used to
restrict the values listed in the drop-down menu of editing form, but it does
not prevent another entity to be selected
[PAS CLAIR]
Relation type definition
------------------------
A relation is defined by a Python class heriting `RelationType`. The name
of the class corresponds to the name of the type. The class then contains
a description of the properties of this type of relation, as well as a
string for the subject and a string for the object. This allows to create
new definition of associated relations, (so that the class can have the
definition properties from the relation)[PAS CLAIR] by example ::
class locked_by(RelationType):
"""relation on all entities indicating that they are locked"""
inlined = True
cardinality = '?*'
subject = '*'
object = 'EUser'
In addition to the permissions, the own properties of the relation types
(shared also by all definition of relation of this type) are:
* `inlined` : boolean handling the physical optimization for archiving
the relation in the subject entity table, instead of creating a specific
table for the relation. This applies to the relation when the cardinality
of subject->relation->object is 0..1 ('?') or 1..1 ('1')
* `symetric` : boolean indication that the relation is symetrical, which
means `X relation Y` implies `Y relation X`
In the case of simultaneous relations definitions, `subject` and `object`
can both be equal to the value of the first argument of `SubjectRelation`
and `ObjectRelation`.
When a relation is not inlined and not symetrical, and it does not require
specific permissions, its definition (by using `SubjectRelation` and
`ObjectRelation`) is all we need.
Permissions definition
----------------------
Define permissions is set through to the attribute `permissions` of entities and
relations types. It defines a dictionnary 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 define in the precreate
of the application (``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_<ACTION>_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 <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
[WHAT IS A NON FINALE 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 thatm 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 assumes/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 [??] `RRQLExpression` on relation types for reading
* special relations "has_<ACTION>_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 checks 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.
[PAS CLAIR]
.. -*- coding: utf-8 -*-
.. _contents:
Appendix
========
.. toctree::
:maxdepth: 1
21-01-architecture.en.txt
21-02-querier.en.txt
21-03-modules-stdlib.en.txt
21-04-modules-cbw-api.en.txt
21-05-mercurial.en.txt
21-06-mercurial-forest.en.txt
.. -*- coding: utf-8 -*-
===================================
Part I - Introduction to `CubicWeb`
===================================
This first part of the book will offer different reading path to
present you with the `CubicWeb` framework, provide a tutorial to get a quick
overview of its features and list its key concepts.
.. toctree::
:maxdepth: 2
A010-book-map.en.txt
A020-tutorial.en.txt
A030-foundation.en.txt
......@@ -18,7 +18,7 @@ An `instance` refers to a specific installation of one or more `cubes`
In this document, we will show you how to create a `cube` and how to use it
in an `instance` for your web application.
.. include:: 01-01-create-cube.en.txt
.. include:: 01-05-components.en.txt
.. include:: 01-06-maintemplate.en.txt
.. include:: 01-07-rss-xml.en.txt
.. include:: A02a-create-cube.en.txt
.. include:: A02b-components.en.txt
.. include:: A02c-maintemplate.en.txt
.. include:: A02d-rss-xml.en.txt
......@@ -29,6 +29,4 @@ software developpment (see http://www.logilab.org), etc.
In 2008, `CubicWeb` was ported for a new type of source : the datastore
from GoogleAppEngine_.
.. include:: 02-01-concepts.en.txt
.. include:: 02-02-registry.en.txt
.. include:: 02-03-configuration.en.txt
.. include:: A03a-concepts.en.txt
.. -*- coding: utf-8 -*-
=====================
Part II - Development
=====================
This part is about developing web applications with the `CubicWeb` framework.
.. toctree::
:maxdepth: 1
B020-define-schema.en.txt
B030-define-views.en.txt
B040-define-workflows.en.txt
B050-data-as-objects.en.txt
B060-form-management.en.txt
B070-ajax-json.en.txt
B080-internationalization.en.txt
B090-ui-components.en.txt
B100-hooks.en.txt
B110-notifications.en.txt
B120-migration.en.txt
B130-tests.en.txt
B140-google-appengine.en.txt
BXXX-actions.en.txt
BXXX-boxes.en.txt
BXXX-configuration.en.txt
BXXX-dbapi.en.txt
BXXX-embedding-external-page.en.txt
BXXX-online-doc.en.txt
BXXX-registry.en.txt
BXXX-repository-operations.en.txt
BXXX-repository-session.en.txt
BXXX-repository-tasks.en.txt
BXXX-request.en.txt
BXXX-sessions.en.txt
BXXX-templates.en.txt
BXXX-urlrewrite.en.txt
......@@ -17,6 +17,6 @@ A relation type could have been implied if none is related to a
relation definition of the schema.
.. include:: 04-01-schema-stdlib.en.txt
.. include:: 04-02-schema-definition.en.txt
.. include:: B021-schema-stdlib.en.txt
.. include:: B022-schema-definition.en.txt
......@@ -210,7 +210,7 @@ forms parameters:
the dictionnary of the forms parameters, before going the classic way (through
step 1 and 2 described juste above)
.. include:: 05-01-views-stdlib.en.txt
.. include:: B031-views-stdlib.en.txt
XML views, binaries...
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment