cubicweb/schemas/bootstrap.py
changeset 11057 0b59724cb3f2
parent 10666 7f6b5f023884
child 11767 432f87a63057
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cubicweb/schemas/bootstrap.py	Sat Jan 16 13:48:51 2016 +0100
@@ -0,0 +1,357 @@
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+"""core CubicWeb schema necessary for bootstrapping the actual instance's schema
+"""
+
+__docformat__ = "restructuredtext en"
+from cubicweb import _
+
+from yams.buildobjs import (EntityType, RelationType, RelationDefinition, Bytes,
+                            SubjectRelation, RichString, String, Boolean, Int)
+from cubicweb.schema import (
+    RQLConstraint,
+    PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS, PUB_SYSTEM_ATTR_PERMS
+    )
+
+# not restricted since as "is" is handled as other relations, guests need
+# access to this
+class CWEType(EntityType):
+    """define an entity type, used to build the instance schema"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    name = String(required=True, indexed=True, internationalizable=True,
+                  unique=True, maxsize=64)
+    description = RichString(internationalizable=True,
+                             description=_('semantic description of this entity type'))
+    # necessary to filter using RQL
+    final = Boolean(default=False, description=_('automatic'))
+
+
+class CWRType(EntityType):
+    """define a relation type, used to build the instance schema"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    name = String(required=True, indexed=True, internationalizable=True,
+                  unique=True, maxsize=64)
+    description = RichString(internationalizable=True,
+                             description=_('semantic description of this relation type'))
+    symmetric = Boolean(description=_('is this relation equivalent in both direction ?'))
+    inlined = Boolean(description=_('is this relation physically inlined? you should know what you\'re doing if you are changing this!'))
+    fulltext_container = String(description=_('if full text content of subject/object entity '
+                                              'should be added to other side entity (the container).'),
+                                vocabulary=('', _('subject'), _('object')),
+                                maxsize=8, default=None)
+    final = Boolean(description=_('automatic'))
+
+
+class CWComputedRType(EntityType):
+    """define a virtual relation type, used to build the instance schema"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    name = String(required=True, indexed=True, internationalizable=True,
+                  unique=True, maxsize=64)
+    description = RichString(internationalizable=True,
+                             description=_('semantic description of this relation type'))
+    rule = String(required=True)
+
+
+class CWAttribute(EntityType):
+    """define a final relation: link a final relation type from a non final
+    entity to a final entity type.
+
+    used to build the instance schema
+    """
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    relation_type = SubjectRelation('CWRType', cardinality='1*',
+                                    constraints=[RQLConstraint('O final TRUE')],
+                                    composite='object')
+    from_entity = SubjectRelation('CWEType', cardinality='1*',
+                                  constraints=[RQLConstraint('O final FALSE')],
+                                  composite='object')
+    to_entity = SubjectRelation('CWEType', cardinality='1*',
+                                constraints=[RQLConstraint('O final TRUE')],
+                                composite='object')
+    constrained_by = SubjectRelation('CWConstraint', cardinality='*1', composite='subject')
+
+    cardinality = String(maxsize=2, internationalizable=True,
+                         vocabulary=[_('?1'), _('11')],
+                         description=_('subject/object cardinality'))
+    ordernum = Int(description=('control subject entity\'s relations order'), default=0)
+
+    formula = String(maxsize=2048)
+    indexed = Boolean(description=_('create an index for quick search on this attribute'))
+    fulltextindexed = Boolean(description=_('index this attribute\'s value in the plain text index'))
+    internationalizable = Boolean(description=_('is this attribute\'s value translatable'))
+    defaultval = Bytes(description=_('default value as gziped pickled python object'))
+    extra_props = Bytes(description=_('additional type specific properties'))
+
+    description = RichString(internationalizable=True,
+                             description=_('semantic description of this attribute'))
+
+
+CARDINALITY_VOCAB = [_('?*'), _('1*'), _('+*'), _('**'),
+                     _('?+'), _('1+'), _('++'), _('*+'),
+                     _('?1'), _('11'), _('+1'), _('*1'),
+                     _('??'), _('1?'), _('+?'), _('*?')]
+
+class CWRelation(EntityType):
+    """define a non final relation: link a non final relation type from a non
+    final entity to a non final entity type.
+
+    used to build the instance schema
+    """
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    relation_type = SubjectRelation('CWRType', cardinality='1*',
+                                    constraints=[RQLConstraint('O final FALSE')],
+                                    composite='object')
+    from_entity = SubjectRelation('CWEType', cardinality='1*',
+                                  constraints=[RQLConstraint('O final FALSE')],
+                                  composite='object')
+    to_entity = SubjectRelation('CWEType', cardinality='1*',
+                                constraints=[RQLConstraint('O final FALSE')],
+                                composite='object')
+    constrained_by = SubjectRelation('CWConstraint', cardinality='*1', composite='subject')
+
+    cardinality = String(maxsize=2, internationalizable=True,
+                         vocabulary=CARDINALITY_VOCAB,
+                         description=_('subject/object cardinality'))
+    ordernum = Int(description=_('control subject entity\'s relations order'),
+                   default=0)
+    composite = String(description=_('is the subject/object entity of the relation '
+                                     'composed of the other ? This implies that when '
+                                     'the composite is deleted, composants are also '
+                                     'deleted.'),
+                       vocabulary=('', _('subject'), _('object')),
+                       maxsize=8, default=None)
+
+    description = RichString(internationalizable=True,
+                             description=_('semantic description of this relation'))
+
+
+# not restricted since it has to be read when checking allowed transitions
+class RQLExpression(EntityType):
+    """define a rql expression used to define permissions"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    exprtype = String(required=True, vocabulary=['ERQLExpression', 'RRQLExpression'])
+    mainvars = String(maxsize=8,
+                      description=_('name of the main variables which should be '
+                                    'used in the selection if necessary (comma '
+                                    'separated)'))
+    expression = String(required=True,
+                        description=_('restriction part of a rql query. '
+                                      'For entity rql expression, X and U are '
+                                      'predefined respectivly to the current object and to '
+                                      'the request user. For relation rql expression, '
+                                      'S, O and U are predefined respectivly to the current '
+                                      'relation\'subject, object and to '
+                                      'the request user. '))
+
+
+class CWConstraint(EntityType):
+    """define a schema constraint"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    cstrtype = SubjectRelation('CWConstraintType', cardinality='1*')
+    value = String(description=_('depends on the constraint type'))
+
+
+class CWUniqueTogetherConstraint(EntityType):
+    """defines a sql-level multicolumn unique index"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    name = String(required=True, unique=True, maxsize=64)
+    constraint_of = SubjectRelation('CWEType', cardinality='1*', composite='object',
+                                    inlined=True)
+    relations = SubjectRelation('CWRType', cardinality='+*',
+                                constraints=[RQLConstraint(
+           'S constraint_of ET, RDEF relation_type O, RDEF from_entity ET, '
+           'O final TRUE OR (O final FALSE AND O inlined TRUE)')])
+
+
+class CWConstraintType(EntityType):
+    """define a schema constraint type"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    name = String(required=True, indexed=True, internationalizable=True,
+                  unique=True, maxsize=64)
+
+
+# not restricted since it has to be read when checking allowed transitions
+class CWGroup(EntityType):
+    """define a CubicWeb users group"""
+    __permissions__ = PUB_SYSTEM_ENTITY_PERMS
+    name = String(required=True, indexed=True, internationalizable=True,
+                  unique=True, maxsize=64)
+
+
+class CWProperty(EntityType):
+    """used for cubicweb configuration. Once a property has been created you
+    can't change the key.
+    """
+    __permissions__ = {
+        'read':   ('managers', 'users', 'guests'),
+        'add':    ('managers', 'users',),
+        'update': ('managers', 'owners',),
+        'delete': ('managers', 'owners',),
+        }
+    # key is a reserved word for mysql
+    pkey = String(required=True, internationalizable=True, maxsize=256,
+                  description=_('defines what\'s the property is applied for. '
+                                'You must select this first to be able to set '
+                                'value'))
+    value = String(internationalizable=True, maxsize=256)
+
+class relation_type(RelationType):
+    """link a relation definition to its relation type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    inlined = True
+
+class from_entity(RelationType):
+    """link a relation definition to its subject entity type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    inlined = True
+
+class to_entity(RelationType):
+    """link a relation definition to its object entity type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    inlined = True
+
+class constrained_by(RelationType):
+    """constraints applying on this relation"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+
+class cstrtype(RelationType):
+    """constraint factory"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    inlined = True
+
+
+class read_permission_cwgroup(RelationDefinition):
+    """groups allowed to read entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'read_permission'
+    subject = ('CWEType', 'CWAttribute', 'CWRelation', 'CWComputedRType')
+    object = 'CWGroup'
+    cardinality = '**'
+
+class add_permission_cwgroup(RelationDefinition):
+    """groups allowed to add entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'add_permission'
+    subject = ('CWEType', 'CWRelation', 'CWAttribute')
+    object = 'CWGroup'
+    cardinality = '**'
+
+class delete_permission_cwgroup(RelationDefinition):
+    """groups allowed to delete entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'delete_permission'
+    subject = ('CWEType', 'CWRelation')
+    object = 'CWGroup'
+    cardinality = '**'
+
+class update_permission_cwgroup(RelationDefinition):
+    """groups allowed to update entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'update_permission'
+    subject = ('CWEType', 'CWAttribute')
+    object = 'CWGroup'
+    cardinality = '**'
+
+class read_permission_rqlexpr(RelationDefinition):
+    """rql expression allowing to read entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'read_permission'
+    subject = ('CWEType', 'CWAttribute', 'CWRelation', 'CWComputedRType')
+    object = 'RQLExpression'
+    cardinality = '*?'
+    composite = 'subject'
+
+class add_permission_rqlexpr(RelationDefinition):
+    """rql expression allowing to add entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'add_permission'
+    subject = ('CWEType', 'CWRelation', 'CWAttribute')
+    object = 'RQLExpression'
+    cardinality = '*?'
+    composite = 'subject'
+
+class delete_permission_rqlexpr(RelationDefinition):
+    """rql expression allowing to delete entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'delete_permission'
+    subject = ('CWEType', 'CWRelation')
+    object = 'RQLExpression'
+    cardinality = '*?'
+    composite = 'subject'
+
+class update_permission_rqlexpr(RelationDefinition):
+    """rql expression allowing to update entities/relations of this type"""
+    __permissions__ = PUB_SYSTEM_REL_PERMS
+    name = 'update_permission'
+    subject = ('CWEType', 'CWAttribute')
+    object = 'RQLExpression'
+    cardinality = '*?'
+    composite = 'subject'
+
+
+class is_(RelationType):
+    """core relation indicating the type of an entity
+    """
+    name = 'is'
+    # don't explicitly set composite here, this is handled anyway
+    #composite = 'object'
+    __permissions__ = {
+        'read':   ('managers', 'users', 'guests'),
+        'add':    (),
+        'delete': (),
+        }
+    cardinality = '1*'
+    subject = '*'
+    object = 'CWEType'
+
+class is_instance_of(RelationType):
+    """core relation indicating the types (including specialized types)
+    of an entity
+    """
+    # don't explicitly set composite here, this is handled anyway
+    #composite = 'object'
+    __permissions__ = {
+        'read':   ('managers', 'users', 'guests'),
+        'add':    (),
+        'delete': (),
+        }
+    cardinality = '+*'
+    subject = '*'
+    object = 'CWEType'
+
+class specializes(RelationType):
+    name = 'specializes'
+    __permissions__ = {
+        'read':   ('managers', 'users', 'guests'),
+        'add':    ('managers',),
+        'delete': ('managers',),
+        }
+    cardinality = '?*'
+    subject = 'CWEType'
+    object = 'CWEType'
+
+def post_build_callback(schema):
+    """set attributes permissions for schema/workflow entities"""
+    from cubicweb.schema import SCHEMA_TYPES, WORKFLOW_TYPES, META_RTYPES
+    wftypes = WORKFLOW_TYPES - set(('TrInfo',))
+    for eschema in schema.entities():
+        if eschema in SCHEMA_TYPES or eschema in wftypes:
+            for rschema in eschema.subject_relations():
+                if rschema.final and not rschema in META_RTYPES:
+                    rdef = eschema.rdef(rschema)
+                    rdef.permissions = PUB_SYSTEM_ATTR_PERMS