schemas/base.py
changeset 11057 0b59724cb3f2
parent 11052 058bb3dc685f
child 11058 23eb30449fe5
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
     1 # copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     3 #
       
     4 # This file is part of CubicWeb.
       
     5 #
       
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     7 # terms of the GNU Lesser General Public License as published by the Free
       
     8 # Software Foundation, either version 2.1 of the License, or (at your option)
       
     9 # any later version.
       
    10 #
       
    11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    14 # details.
       
    15 #
       
    16 # You should have received a copy of the GNU Lesser General Public License along
       
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    18 """core CubicWeb schema, but not necessary at bootstrap time"""
       
    19 
       
    20 __docformat__ = "restructuredtext en"
       
    21 from cubicweb import _
       
    22 
       
    23 from yams.buildobjs import (EntityType, RelationType, RelationDefinition,
       
    24                             SubjectRelation,
       
    25                             String, TZDatetime, Datetime, Password, Interval,
       
    26                             Boolean, UniqueConstraint)
       
    27 from cubicweb.schema import (
       
    28     RQLConstraint, WorkflowableEntityType, ERQLExpression, RRQLExpression,
       
    29     PUB_SYSTEM_ENTITY_PERMS, PUB_SYSTEM_REL_PERMS, PUB_SYSTEM_ATTR_PERMS,
       
    30     RO_ATTR_PERMS)
       
    31 
       
    32 class CWUser(WorkflowableEntityType):
       
    33     """define a CubicWeb user"""
       
    34     __permissions__ = {
       
    35         'read':   ('managers', 'users', ERQLExpression('X identity U')),
       
    36         'add':    ('managers',),
       
    37         'delete': ('managers',),
       
    38         'update': ('managers', ERQLExpression('X identity U, NOT U in_group G, G name "guests"'),),
       
    39         }
       
    40 
       
    41     login     = String(required=True, unique=True, maxsize=64,
       
    42                        description=_('unique identifier used to connect to the application'))
       
    43     upassword = Password(required=True) # password is a reserved word for mysql
       
    44     firstname = String(maxsize=64)
       
    45     surname   = String(maxsize=64)
       
    46     last_login_time = TZDatetime(description=_('last connection date'))
       
    47     in_group = SubjectRelation('CWGroup', cardinality='+*',
       
    48                                constraints=[RQLConstraint('NOT O name "owners"')],
       
    49                                description=_('groups grant permissions to the user'))
       
    50 
       
    51 
       
    52 class EmailAddress(EntityType):
       
    53     """an electronic mail address associated to a short alias"""
       
    54     __permissions__ = {
       
    55         # application that wishes public email, or use it for something else
       
    56         # than users (eg Company, Person), should explicitly change permissions
       
    57         'read':   ('managers', ERQLExpression('U use_email X')),
       
    58         'add':    ('managers', 'users',),
       
    59         'delete': ('managers', 'owners', ERQLExpression('P use_email X, U has_update_permission P')),
       
    60         'update': ('managers', 'owners', ERQLExpression('P use_email X, U has_update_permission P')),
       
    61         }
       
    62 
       
    63     alias   = String(fulltextindexed=True, maxsize=56)
       
    64     address = String(required=True,  fulltextindexed=True,
       
    65                      indexed=True, unique=True, maxsize=128)
       
    66     prefered_form = SubjectRelation('EmailAddress', cardinality='?*',
       
    67                                     description=_('when multiple addresses are equivalent \
       
    68 (such as python-projects@logilab.org and python-projects@lists.logilab.org), set this \
       
    69 to indicate which is the preferred form.'))
       
    70 
       
    71 class use_email(RelationType):
       
    72     fulltext_container = 'subject'
       
    73 
       
    74 
       
    75 class use_email_relation(RelationDefinition):
       
    76     """user's email account"""
       
    77     name = "use_email"
       
    78     __permissions__ = {
       
    79         'read':   ('managers', 'users', 'guests',),
       
    80         'add':    ('managers', RRQLExpression('U has_update_permission S'),),
       
    81         'delete': ('managers', RRQLExpression('U has_update_permission S'),),
       
    82         }
       
    83     subject = "CWUser"
       
    84     object = "EmailAddress"
       
    85     cardinality = '*?'
       
    86     composite = 'subject'
       
    87 
       
    88 
       
    89 class primary_email(RelationDefinition):
       
    90     """the prefered email"""
       
    91     __permissions__ = {
       
    92         'read':   ('managers', 'users', 'guests',),
       
    93         'add':    ('managers', RRQLExpression('U has_update_permission S'),),
       
    94         'delete': ('managers', RRQLExpression('U has_update_permission S'),),
       
    95         }
       
    96     subject = "CWUser"
       
    97     object = "EmailAddress"
       
    98     cardinality = '??'
       
    99     constraints= [RQLConstraint('S use_email O')]
       
   100 
       
   101 
       
   102 class prefered_form(RelationType):
       
   103     __permissions__ = {
       
   104         'read':   ('managers', 'users', 'guests',),
       
   105         # XXX should have update __permissions__ on both subject and object,
       
   106         #     though by doing this we will probably have no way to add
       
   107         #     this relation in the web ui. The easiest way to acheive this
       
   108         #     is probably to be able to have "U has_update_permission O" as
       
   109         #     RQLConstraint of the relation definition, though this is not yet
       
   110         #     possible
       
   111         'add':    ('managers', RRQLExpression('U has_update_permission S'),),
       
   112         'delete': ('managers', RRQLExpression('U has_update_permission S'),),
       
   113         }
       
   114 
       
   115 class in_group(RelationType):
       
   116     """core relation indicating a user's groups"""
       
   117     __permissions__ = PUB_SYSTEM_REL_PERMS
       
   118 
       
   119 class owned_by(RelationType):
       
   120     """core relation indicating owners of an entity. This relation
       
   121     implicitly put the owner into the owners group for the entity
       
   122     """
       
   123     __permissions__ = {
       
   124         'read':   ('managers', 'users', 'guests'),
       
   125         'add':    ('managers', RRQLExpression('S owned_by U'),),
       
   126         'delete': ('managers', RRQLExpression('S owned_by U'),),
       
   127         }
       
   128     # 0..n cardinality for entities created by internal session (no attached user)
       
   129     # and to support later deletion of a user which has created some entities
       
   130     cardinality = '**'
       
   131     subject = '*'
       
   132     object = 'CWUser'
       
   133 
       
   134 class created_by(RelationType):
       
   135     """core relation indicating the original creator of an entity"""
       
   136     __permissions__ = {
       
   137         'read':   ('managers', 'users', 'guests'),
       
   138         'add':    ('managers',),
       
   139         'delete': ('managers',),
       
   140         }
       
   141     # 0..1 cardinality for entities created by internal session (no attached user)
       
   142     # and to support later deletion of a user which has created some entities
       
   143     cardinality = '?*'
       
   144     subject = '*'
       
   145     object = 'CWUser'
       
   146 
       
   147 
       
   148 class creation_date(RelationType):
       
   149     """creation time of an entity"""
       
   150     __permissions__ = PUB_SYSTEM_ATTR_PERMS
       
   151     cardinality = '11'
       
   152     subject = '*'
       
   153     object = 'TZDatetime'
       
   154 
       
   155 
       
   156 class modification_date(RelationType):
       
   157     """latest modification time of an entity"""
       
   158     __permissions__ = PUB_SYSTEM_ATTR_PERMS
       
   159     cardinality = '11'
       
   160     subject = '*'
       
   161     object = 'TZDatetime'
       
   162 
       
   163 
       
   164 class cwuri(RelationType):
       
   165     """internal entity uri"""
       
   166     __permissions__ = RO_ATTR_PERMS
       
   167     cardinality = '11'
       
   168     subject = '*'
       
   169     object = 'String'
       
   170 
       
   171 
       
   172 # XXX find a better relation name
       
   173 class for_user(RelationType):
       
   174     """link a property to the user which want this property customization. Unless
       
   175     you're a site manager, this relation will be handled automatically.
       
   176     """
       
   177     __permissions__ = {
       
   178         'read':   ('managers', 'users', 'guests'),
       
   179         'add':    ('managers',),
       
   180         'delete': ('managers',),
       
   181         }
       
   182     inlined = True
       
   183     subject = 'CWProperty'
       
   184     object = 'CWUser'
       
   185     composite = 'object'
       
   186     cardinality = '?*'
       
   187 
       
   188 
       
   189 class ExternalUri(EntityType):
       
   190     """a URI representing an object in external data store"""
       
   191     uri = String(required=True, unique=True, maxsize=256,
       
   192                  description=_('the URI of the object'))
       
   193 
       
   194 
       
   195 class same_as(RelationType):
       
   196     """generic relation to specify that an external entity represent the same
       
   197     object as a local one:
       
   198        http://www.w3.org/TR/owl-ref/#sameAs-def
       
   199     """
       
   200     #NOTE: You'll have to explicitly declare which entity types can have a
       
   201     #same_as relation
       
   202     __permissions__ = {
       
   203         'read':   ('managers', 'users', 'guests',),
       
   204         'add':    ('managers', 'users'),
       
   205         'delete': ('managers', 'owners'),
       
   206         }
       
   207     cardinality = '**'
       
   208     symmetric = True
       
   209     # NOTE: the 'object = ExternalUri' declaration will still be mandatory
       
   210     #       in the cube's schema.
       
   211     object = 'ExternalUri'
       
   212 
       
   213 
       
   214 class CWCache(EntityType):
       
   215     """a simple cache entity characterized by a name and
       
   216     a validity date.
       
   217 
       
   218     The target application is responsible for updating timestamp
       
   219     when necessary to invalidate the cache (typically in hooks).
       
   220 
       
   221     Also, checkout the AppObject.get_cache() method.
       
   222     """
       
   223     # XXX only handle by hooks, shouldn't be readable/editable at all through
       
   224     # the ui and so no permissions should be granted, no?
       
   225     __permissions__ = {
       
   226         'read':   ('managers', 'users', 'guests'),
       
   227         'add':    ('managers',),
       
   228         'update': ('managers', 'users',), # XXX
       
   229         'delete': ('managers',),
       
   230         }
       
   231 
       
   232     name = String(required=True, unique=True, maxsize=128,
       
   233                   description=_('name of the cache'))
       
   234     timestamp = TZDatetime(default='NOW')
       
   235 
       
   236 
       
   237 class CWSource(EntityType):
       
   238     __permissions__ = {
       
   239         'read':   ('managers', 'users', 'guests'),
       
   240         'add':    ('managers',),
       
   241         'update': ('managers',),
       
   242         'delete': ('managers',),
       
   243         }
       
   244     name = String(required=True, unique=True, maxsize=128,
       
   245                   description=_('name of the source'))
       
   246     type = String(required=True, maxsize=20, description=_('type of the source'))
       
   247     config = String(description=_('source\'s configuration. One key=value per '
       
   248                                   'line, authorized keys depending on the '
       
   249                                   'source\'s type'),
       
   250                     __permissions__={
       
   251                         'read':   ('managers',),
       
   252                         'add':    ('managers',),
       
   253                         'update': ('managers',),
       
   254                         })
       
   255     # put this here and not in a subclass even if it's only for some sources
       
   256     # since having subclasses on generic relation (cw_source) double the number
       
   257     # of rdef in the schema, and make ms planning harder since queries solutions
       
   258     # may changes when sources are specified
       
   259     url = String(description=_('URLs from which content will be imported. You can put one url per line'))
       
   260     parser = String(description=_('parser to use to extract entities from content retrieved at given URLs.'))
       
   261     latest_retrieval = TZDatetime(description=_('latest synchronization time'))
       
   262     in_synchronization = TZDatetime(description=_('start timestamp of the currently in synchronization, or NULL when no synchronization in progress.'))
       
   263 
       
   264 
       
   265 ENTITY_MANAGERS_PERMISSIONS = {
       
   266     'read':   ('managers',),
       
   267     'add':    ('managers',),
       
   268     'update': ('managers',),
       
   269     'delete': ('managers',),
       
   270     }
       
   271 RELATION_MANAGERS_PERMISSIONS = {
       
   272     'read':   ('managers',),
       
   273     'add':    ('managers',),
       
   274     'delete': ('managers',),
       
   275     }
       
   276 
       
   277 
       
   278 class CWSourceHostConfig(EntityType):
       
   279     __permissions__ = ENTITY_MANAGERS_PERMISSIONS
       
   280     __unique_together__ = [('match_host', 'cw_host_config_of')]
       
   281     match_host = String(required=True, maxsize=128,
       
   282                         description=_('regexp matching host(s) to which this config applies'))
       
   283     config = String(required=True,
       
   284                     description=_('Source\'s configuration for a particular host. '
       
   285                                   'One key=value per line, authorized keys '
       
   286                                   'depending on the source\'s type, overriding '
       
   287                                   'values defined on the source.'),
       
   288                     __permissions__={
       
   289                         'read':   ('managers',),
       
   290                         'add':    ('managers',),
       
   291                         'update': ('managers',),
       
   292                         })
       
   293 
       
   294 
       
   295 class cw_host_config_of(RelationDefinition):
       
   296     __permissions__ = RELATION_MANAGERS_PERMISSIONS
       
   297     subject = 'CWSourceHostConfig'
       
   298     object = 'CWSource'
       
   299     cardinality = '1*'
       
   300     composite = 'object'
       
   301     inlined = True
       
   302 
       
   303 class cw_source(RelationDefinition):
       
   304     __permissions__ = {
       
   305         'read':   ('managers', 'users', 'guests'),
       
   306         'add':    ('managers',),
       
   307         'delete': ('managers',),
       
   308         }
       
   309     subject = '*'
       
   310     object = 'CWSource'
       
   311     cardinality = '1*'
       
   312     composite = 'object'
       
   313 
       
   314 
       
   315 class CWDataImport(EntityType):
       
   316     __permissions__ = ENTITY_MANAGERS_PERMISSIONS
       
   317     start_timestamp = TZDatetime()
       
   318     end_timestamp = TZDatetime()
       
   319     log = String()
       
   320     status = String(required=True, internationalizable=True, indexed=True,
       
   321                     default='in progress',
       
   322                     vocabulary=[_('in progress'), _('success'), _('failed')])
       
   323 
       
   324 class cw_import_of(RelationDefinition):
       
   325     __permissions__ = RELATION_MANAGERS_PERMISSIONS
       
   326     subject = 'CWDataImport'
       
   327     object = 'CWSource'
       
   328     cardinality = '1*'
       
   329     composite = 'object'
       
   330 
       
   331 
       
   332 class CWSourceSchemaConfig(EntityType):
       
   333     __permissions__ = ENTITY_MANAGERS_PERMISSIONS
       
   334     cw_for_source = SubjectRelation(
       
   335         'CWSource', inlined=True, cardinality='1*', composite='object',
       
   336         __permissions__=RELATION_MANAGERS_PERMISSIONS)
       
   337     options = String(description=_('allowed options depends on the source type'))
       
   338 
       
   339 
       
   340 class rtype_cw_schema(RelationDefinition):
       
   341     __permissions__ = RELATION_MANAGERS_PERMISSIONS
       
   342     name = 'cw_schema'
       
   343     subject = 'CWSourceSchemaConfig'
       
   344     object = ('CWEType', 'CWRType')
       
   345     inlined = True
       
   346     cardinality = '1*'
       
   347     composite = 'object'
       
   348     constraints = [RQLConstraint('NOT O final TRUE')]
       
   349 
       
   350 class rdef_cw_schema(RelationDefinition):
       
   351     __permissions__ = RELATION_MANAGERS_PERMISSIONS
       
   352     name = 'cw_schema'
       
   353     subject = 'CWSourceSchemaConfig'
       
   354     object = 'CWRelation'
       
   355     inlined = True
       
   356     cardinality = '1*'
       
   357     composite = 'object'
       
   358 
       
   359 # "abtract" relation types, no definition in cubicweb itself ###################
       
   360 
       
   361 class identical_to(RelationType):
       
   362     """identical to"""
       
   363     symmetric = True
       
   364     __permissions__ = {
       
   365         'read':   ('managers', 'users', 'guests',),
       
   366         # XXX should have update __permissions__ on both subject and object,
       
   367         #     though by doing this we will probably have no way to add
       
   368         #     this relation in the web ui. The easiest way to acheive this
       
   369         #     is probably to be able to have "U has_update_permission O" as
       
   370         #     RQLConstraint of the relation definition, though this is not yet
       
   371         #     possible
       
   372         'add':    ('managers', RRQLExpression('U has_update_permission S'),),
       
   373         'delete': ('managers', RRQLExpression('U has_update_permission S'),),
       
   374         }
       
   375 
       
   376 class see_also(RelationType):
       
   377     """generic relation to link one entity to another"""
       
   378     symmetric = True
       
   379     __permissions__ = {
       
   380         'read':   ('managers', 'users', 'guests',),
       
   381         'add':    ('managers', RRQLExpression('U has_update_permission S'),),
       
   382         'delete': ('managers', RRQLExpression('U has_update_permission S'),),
       
   383         }