schema.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 13 Sep 2010 12:24:11 +0200
branchstable
changeset 6218 d37428222a63
parent 6191 ece6996e6ac8
child 6229 c4a70a5dd144
permissions -rw-r--r--
[form fields] option may be a 3-uple (3d element being dict containing widget options)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
6017
5f6a60ea8544 [relations in ui] provide context information when computing label for a relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5896
diff changeset
    18
"""classes to define schemas for CubicWeb"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    21
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
import re
2147
476a75ede2cc merge and add missing import in schema.py
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2142
diff changeset
    24
from os.path import join
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
from logging import getLogger
1133
8a409ea0c9ec more linting
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
    26
from warnings import warn
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
624
258e5692ae06 provide a new RichString attribute type
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 479
diff changeset
    28
from logilab.common.decorators import cached, clear_cache, monkeypatch
2730
bb6fcb8c5d71 to make cw schemas importable, they have to be installed w/ cw code, not in /usr/share/cubicweb/schemas
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2718
diff changeset
    29
from logilab.common.logging_ext import set_log_methods
4717
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
    30
from logilab.common.deprecation import deprecated, class_moved
2926
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
    31
from logilab.common.graph import get_cycles
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
from logilab.common.compat import any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
2531
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
    34
from yams import BadSchemaDefinition, buildobjs as ybo
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
    35
from yams.schema import Schema, ERSchema, EntitySchema, RelationSchema, \
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
    36
     RelationDefinitionSchema, PermissionMixIn, role_name
4717
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
    37
from yams.constraints import BaseConstraint, FormatConstraint
2531
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
    38
from yams.reader import (CONSTRAINTS, PyFileReader, SchemaLoader,
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
    39
                         obsolete as yobsolete, cleanup_sys_modules)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
from rql import parse, nodes, RQLSyntaxError, TypeResolverException
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
2730
bb6fcb8c5d71 to make cw schemas importable, they have to be installed w/ cw code, not in /usr/share/cubicweb/schemas
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2718
diff changeset
    43
import cubicweb
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
2596
d02eed70937f [R repo, schema] use VIRTUAL_RTYPES const
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2531
diff changeset
    46
PURE_VIRTUAL_RTYPES = set(('identity', 'has_text',))
d02eed70937f [R repo, schema] use VIRTUAL_RTYPES const
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2531
diff changeset
    47
VIRTUAL_RTYPES = set(('eid', 'identity', 'has_text',))
d02eed70937f [R repo, schema] use VIRTUAL_RTYPES const
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2531
diff changeset
    48
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4843
diff changeset
    49
# set of meta-relations available for every entity types
2622
3c7edaa6c6d2 oops, should have been in a earlier commit (META_RELATION_TYPES renaming)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2616
diff changeset
    50
META_RTYPES = set((
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    51
    'owned_by', 'created_by', 'is', 'is_instance_of', 'identity',
2456
aa25d6b244c8 new cwuri metadata + a few tests fixes on the way
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2437
diff changeset
    52
    'eid', 'creation_date', 'modification_date', 'has_text', 'cwuri',
2184
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2181
diff changeset
    53
    ))
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4843
diff changeset
    54
SYSTEM_RTYPES = set(('require_permission', 'custom_workflow', 'in_state',
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4843
diff changeset
    55
                     'wf_info_for'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4843
diff changeset
    57
# set of entity and relation types used to build the schema
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    58
SCHEMA_TYPES = set((
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    59
    'CWEType', 'CWRType', 'CWAttribute', 'CWRelation',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    60
    'CWConstraint', 'CWConstraintType', 'RQLExpression',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    61
    'relation_type', 'from_entity', 'to_entity',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    62
    'constrained_by', 'cstrtype',
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    63
    ))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
4434
101344a6ff9b Improve the schema command with filtering option.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4252
diff changeset
    65
WORKFLOW_TYPES = set(('Transition', 'State', 'TrInfo', 'Workflow',
4759
af2e6c377c71 cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4757
diff changeset
    66
                      'WorkflowTransition', 'BaseTransition',
af2e6c377c71 cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4757
diff changeset
    67
                      'SubWorkflowExitPoint'))
af2e6c377c71 cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4757
diff changeset
    68
4434
101344a6ff9b Improve the schema command with filtering option.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4252
diff changeset
    69
INTERNAL_TYPES = set(('CWProperty', 'CWPermission', 'CWCache', 'ExternalUri'))
101344a6ff9b Improve the schema command with filtering option.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4252
diff changeset
    70
101344a6ff9b Improve the schema command with filtering option.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4252
diff changeset
    71
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    72
_LOGGER = getLogger('cubicweb.schemaloader')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
# schema entities created from serialized schema have an eid rproperty
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
ybo.ETYPE_PROPERTIES += ('eid',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
ybo.RTYPE_PROPERTIES += ('eid',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
ybo.RDEF_PROPERTIES += ('eid',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
2926
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
    79
4754
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    80
PUB_SYSTEM_ENTITY_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    81
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    82
    'add':    ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    83
    'delete': ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    84
    'update': ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    85
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    86
PUB_SYSTEM_REL_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    87
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    88
    'add':    ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    89
    'delete': ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    90
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    91
PUB_SYSTEM_ATTR_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    92
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    93
    'update':    ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    94
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    95
RO_REL_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    96
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    97
    'add':    (),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    98
    'delete': (),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
    99
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   100
RO_ATTR_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   101
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   102
    'update': (),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   103
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   104
2926
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   105
# XXX same algorithm as in reorder_cubes and probably other place,
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   106
# may probably extract a generic function
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   107
def order_eschemas(eschemas):
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   108
    """return entity schemas ordered such that entity types which specializes an
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   109
    other one appears after that one
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   110
    """
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   111
    graph = {}
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   112
    for eschema in eschemas:
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   113
        if eschema.specializes():
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   114
            graph[eschema] = set((eschema.specializes(),))
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   115
        else:
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   116
            graph[eschema] = set()
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   117
    cycles = get_cycles(graph)
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   118
    if cycles:
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   119
        cycles = '\n'.join(' -> '.join(cycle) for cycle in cycles)
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   120
        raise Exception('cycles in entity schema specialization: %s'
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   121
                        % cycles)
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   122
    eschemas = []
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   123
    while graph:
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   124
        # sorted to get predictable results
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   125
        for eschema, deps in sorted(graph.items()):
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   126
            if not deps:
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   127
                eschemas.append(eschema)
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   128
                del graph[eschema]
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   129
                for deps in graph.itervalues():
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   130
                    try:
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   131
                        deps.remove(eschema)
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   132
                    except KeyError:
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   133
                        continue
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   134
    return eschemas
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   135
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
def bw_normalize_etype(etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
    if etype in ETYPE_NAME_MAP:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
        msg = '%s has been renamed to %s, please update your code' % (
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   139
            etype, ETYPE_NAME_MAP[etype])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        warn(msg, DeprecationWarning, stacklevel=4)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        etype = ETYPE_NAME_MAP[etype]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    return etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
3275
5247789df541 [gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3240
diff changeset
   144
def display_name(req, key, form='', context=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
    """return a internationalized string for the key (schema entity or relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
    name) in a given form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
    assert form in ('', 'plural', 'subject', 'object')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
    if form == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        form = ''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
    if form:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
        key = key + '_' + form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
    # ensure unicode
3284
036cf5a25714 ensure pgettext return unicode as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3275
diff changeset
   154
    # .lower() in case no translation are available XXX done whatever a translation is there or not!
036cf5a25714 ensure pgettext return unicode as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3275
diff changeset
   155
    if context is not None:
036cf5a25714 ensure pgettext return unicode as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3275
diff changeset
   156
        return unicode(req.pgettext(context, key)).lower()
3275
5247789df541 [gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3240
diff changeset
   157
    else:
5247789df541 [gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3240
diff changeset
   158
        return unicode(req._(key)).lower()
5247789df541 [gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3240
diff changeset
   159
2788
8d3dbe577d3a R put version info in deprecation warnings
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2782
diff changeset
   160
__builtins__['display_name'] = deprecated('[3.4] display_name should be imported from cubicweb.schema')(display_name)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   162
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   163
# rql expression utilities function ############################################
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   164
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   165
def guess_rrqlexpr_mainvars(expression):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   166
    defined = set(split_expression(expression))
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   167
    mainvars = []
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   168
    if 'S' in defined:
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   169
        mainvars.append('S')
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   170
    if 'O' in defined:
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   171
        mainvars.append('O')
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   172
    if 'U' in defined:
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   173
        mainvars.append('U')
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   174
    if not mainvars:
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   175
        raise Exception('unable to guess selection variables')
5372
b74eed7e8b37 Add a basic script to compare the db_schema to the fs_schema.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5174
diff changeset
   176
    return ','.join(sorted(mainvars))
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   177
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   178
def split_expression(rqlstring):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   179
    for expr in rqlstring.split(','):
4132
440d383367eb fix mainvars detection bug with EXISTS (paren, actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3985
diff changeset
   180
        for noparen in expr.split('('):
440d383367eb fix mainvars detection bug with EXISTS (paren, actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3985
diff changeset
   181
            for word in noparen.split():
440d383367eb fix mainvars detection bug with EXISTS (paren, actually)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3985
diff changeset
   182
                yield word
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   183
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   184
def normalize_expression(rqlstring):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   185
    """normalize an rql expression to ease schema synchronization (avoid
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   186
    suppressing and reinserting an expression if only a space has been added/removed
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   187
    for instance)
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   188
    """
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   189
    return u', '.join(' '.join(expr.split()) for expr in rqlstring.split(','))
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   190
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   191
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   192
# Schema objects definition ###################################################
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   193
3471
8c57c71b859c can now give context to rschema.display_name(...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3401
diff changeset
   194
def ERSchema_display_name(self, req, form='', context=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    """return a internationalized string for the entity/relation type name in
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
    a given form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
    """
3471
8c57c71b859c can now give context to rschema.display_name(...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3401
diff changeset
   198
    return display_name(req, self.type, form, context)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
ERSchema.display_name = ERSchema_display_name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
@cached
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   202
def get_groups(self, action):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
    """return the groups authorized to perform <action> on entities of
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
    this type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
    :rtype: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
    :return: names of the groups with the given permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
    #assert action in self._groups, '%s %s' % (self, action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
    try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   215
        return frozenset(g for g in self.permissions[action] if isinstance(g, basestring))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
    except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        return ()
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   218
PermissionMixIn.get_groups = get_groups
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
@cached
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   221
def get_rqlexprs(self, action):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
    """return the rql expressions representing queries to check the user is allowed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
    to perform <action> on entities of this type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
    :rtype: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
    :return: the rql expressions with the given permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
    #assert action in self._rqlexprs, '%s %s' % (self, action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
    try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   234
        return tuple(g for g in self.permissions[action] if not isinstance(g, basestring))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
    except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
        return ()
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   237
PermissionMixIn.get_rqlexprs = get_rqlexprs
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   239
orig_set_action_permissions = PermissionMixIn.set_action_permissions
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   240
def set_action_permissions(self, action, permissions):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
    """set the groups and rql expressions allowing to perform <action> on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
    entities of this type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
    :type permissions: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
    :param permissions: the groups and rql expressions allowing the given action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
    """
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   250
    orig_set_action_permissions(self, action, tuple(permissions))
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   251
    clear_cache(self, 'get_rqlexprs')
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   252
    clear_cache(self, 'get_groups')
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   253
PermissionMixIn.set_action_permissions = set_action_permissions
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   255
def has_local_role(self, action):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
    """return true if the action *may* be granted localy (eg either rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
    expressions or the owners group are used in security definition)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
    XXX this method is only there since we don't know well how to deal with
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
    'add' action checking. Also find a better name would be nice.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
    if self.get_rqlexprs(action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
    if action in ('update', 'delete'):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   266
        return 'owners' in self.get_groups(action)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
    return False
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   268
PermissionMixIn.has_local_role = has_local_role
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   269
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   270
def may_have_permission(self, action, req):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   271
    if action != 'read' and not (self.has_local_role('read') or
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   272
                                 self.has_perm(req, 'read')):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   273
        return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   274
    return self.has_local_role(action) or self.has_perm(req, action)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   275
PermissionMixIn.may_have_permission = may_have_permission
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   276
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   277
def has_perm(self, session, action, **kwargs):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   278
    """return true if the action is granted globaly or localy"""
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   279
    try:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   280
        self.check_perm(session, action, **kwargs)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   281
        return True
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   282
    except Unauthorized:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   283
        return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   284
PermissionMixIn.has_perm = has_perm
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   285
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   286
def check_perm(self, session, action, **kwargs):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   287
    # NB: session may be a server session or a request object check user is
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   288
    # in an allowed group, if so that's enough internal sessions should
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   289
    # always stop there
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   290
    groups = self.get_groups(action)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   291
    if session.user.matching_groups(groups):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   292
        return
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   293
    # if 'owners' in allowed groups, check if the user actually owns this
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   294
    # object, if so that's enough
4607
55eab66c6592 [schema security] fix so that when cheking attributes perms for an entity being created, 'owners' and has_*_permission in erqlexpr are considered satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4586
diff changeset
   295
    if 'owners' in groups and (
55eab66c6592 [schema security] fix so that when cheking attributes perms for an entity being created, 'owners' and has_*_permission in erqlexpr are considered satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4586
diff changeset
   296
          kwargs.get('creating')
4608
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4607
diff changeset
   297
          or ('eid' in kwargs and session.user.owns(kwargs['eid']))):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   298
        return
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   299
    # else if there is some rql expressions, check them
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   300
    if any(rqlexpr.check(session, **kwargs)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   301
           for rqlexpr in self.get_rqlexprs(action)):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   302
        return
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   303
    raise Unauthorized(action, str(self))
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   304
PermissionMixIn.check_perm = check_perm
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   305
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   306
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   307
RelationDefinitionSchema._RPROPERTIES['eid'] = None
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   308
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   309
def rql_expression(self, expression, mainvars=None, eid=None):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   310
    """rql expression factory"""
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   311
    if self.rtype.final:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   312
        return ERQLExpression(expression, mainvars, eid)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   313
    return RRQLExpression(expression, mainvars, eid)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   314
RelationDefinitionSchema.rql_expression = rql_expression
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   315
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   316
orig_check_permission_definitions = RelationDefinitionSchema.check_permission_definitions
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   317
def check_permission_definitions(self):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   318
    orig_check_permission_definitions(self)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   319
    schema = self.subject.schema
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   320
    for action, groups in self.permissions.iteritems():
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   321
        for group_or_rqlexpr in groups:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   322
            if action == 'read' and \
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   323
                   isinstance(group_or_rqlexpr, RQLExpression):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   324
                msg = "can't use rql expression for read permission of %s"
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   325
                raise BadSchemaDefinition(msg % self)
4574
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   326
            if self.final and isinstance(group_or_rqlexpr, RRQLExpression):
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   327
                msg = "can't use RRQLExpression on %s, use an ERQLExpression"
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   328
                raise BadSchemaDefinition(msg % self)
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   329
            if not self.final and isinstance(group_or_rqlexpr, ERQLExpression):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   330
                msg = "can't use ERQLExpression on %s, use a RRQLExpression"
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   331
                raise BadSchemaDefinition(msg % self)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   332
RelationDefinitionSchema.check_permission_definitions = check_permission_definitions
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
class CubicWebEntitySchema(EntitySchema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
    """a entity has a type, a set of subject and or object relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   337
    the entity schema defines the possible relations for a given type and some
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
    constraints on those relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
    def __init__(self, schema=None, edef=None, eid=None, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
        super(CubicWebEntitySchema, self).__init__(schema, edef, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
        if eid is None and edef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
            eid = getattr(edef, 'eid', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
        self.eid = eid
4574
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   345
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   346
    def check_permission_definitions(self):
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   347
        super(CubicWebEntitySchema, self).check_permission_definitions()
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   348
        for groups in self.permissions.itervalues():
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   349
            for group_or_rqlexpr in groups:
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   350
                if isinstance(group_or_rqlexpr, RRQLExpression):
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   351
                    msg = "can't use RRQLExpression on %s, use an ERQLExpression"
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   352
                    raise BadSchemaDefinition(msg % self.type)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   353
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
    def attribute_definitions(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
        """return an iterator on attribute definitions
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   356
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
        attribute relations are a subset of subject relations where the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
        object's type is a final entity
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   359
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
        an attribute definition is a 2-uple :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
        * name of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
        * schema of the destination entity type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   364
        iter = super(CubicWebEntitySchema, self).attribute_definitions()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
        for rschema, attrschema in iter:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
            if rschema.type == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   368
            yield rschema, attrschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   369
2128
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   370
    def main_attribute(self):
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   371
        """convenience method that returns the *main* (i.e. the first non meta)
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   372
        attribute defined in the entity schema
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   373
        """
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   374
        for rschema, _ in self.attribute_definitions():
2622
3c7edaa6c6d2 oops, should have been in a earlier commit (META_RELATION_TYPES renaming)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2616
diff changeset
   375
            if not (rschema in META_RTYPES
2128
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   376
                    or self.is_metadata(rschema)):
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   377
                return rschema
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   378
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
    def add_subject_relation(self, rschema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
        """register the relation schema as possible subject relation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
        super(CubicWebEntitySchema, self).add_subject_relation(rschema)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
        self._update_has_text()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
    def del_subject_relation(self, rtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
        super(CubicWebEntitySchema, self).del_subject_relation(rtype)
2632
920bfaff60a4 B [schema update] may remove has_text unexpectedly, give another argument to fix it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2622
diff changeset
   386
        self._update_has_text(True)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   387
2632
920bfaff60a4 B [schema update] may remove has_text unexpectedly, give another argument to fix it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2622
diff changeset
   388
    def _update_has_text(self, deletion=False):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
        may_need_has_text, has_has_text = False, False
2632
920bfaff60a4 B [schema update] may remove has_text unexpectedly, give another argument to fix it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2622
diff changeset
   390
        need_has_text = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
        for rschema in self.subject_relations():
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   392
            if rschema.final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
                if rschema == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
                    has_has_text = True
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   395
                elif self.rdef(rschema).get('fulltextindexed'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
            elif rschema.fulltext_container:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
                if rschema.fulltext_container == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
                    need_has_text = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
        for rschema in self.object_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
            if rschema.fulltext_container:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
                if rschema.fulltext_container == 'object':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
                    need_has_text = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
        if need_has_text is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
            need_has_text = may_need_has_text
2632
920bfaff60a4 B [schema update] may remove has_text unexpectedly, give another argument to fix it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2622
diff changeset
   410
        if need_has_text and not has_has_text and not deletion:
4755
13a5d3a7410e [schema] tweaks meta-relations and schema/workflow entities attributes permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4754
diff changeset
   411
            rdef = ybo.RelationDefinition(self.type, 'has_text', 'String',
13a5d3a7410e [schema] tweaks meta-relations and schema/workflow entities attributes permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4754
diff changeset
   412
                                          __permissions__=RO_ATTR_PERMS)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   413
            self.schema.add_relation_def(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   414
        elif not need_has_text and has_has_text:
5122
c06078d59e87 [schema] ensure we don't remove has_text relation type unfortunatly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   415
            # use rschema.del_relation_def and not schema.del_relation_def to
c06078d59e87 [schema] ensure we don't remove has_text relation type unfortunatly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   416
            # avoid deleting the relation type accidentally...
c06078d59e87 [schema] ensure we don't remove has_text relation type unfortunatly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   417
            self.schema['has_text'].del_relation_def(self, self.schema['String'])
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   418
5896
67683b7e591a cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
   419
    def schema_entity(self): # XXX @property for consistency with meta
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
        """return True if this entity type is used to build the schema"""
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   421
        return self.type in SCHEMA_TYPES
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   423
    def rql_expression(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
        """rql expression factory"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
        return ERQLExpression(expression, mainvars, eid)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   426
2252
dd9758cb77e1 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2222
diff changeset
   427
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   428
class CubicWebRelationSchema(RelationSchema):
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   429
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   430
    def __init__(self, schema=None, rdef=None, eid=None, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
        if rdef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
            # if this relation is inlined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
            self.inlined = rdef.inlined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
        super(CubicWebRelationSchema, self).__init__(schema, rdef, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
        if eid is None and rdef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
            eid = getattr(rdef, 'eid', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
        self.eid = eid
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   438
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   439
    @property
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   440
    def meta(self):
2622
3c7edaa6c6d2 oops, should have been in a earlier commit (META_RELATION_TYPES renaming)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2616
diff changeset
   441
        return self.type in META_RTYPES
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   442
5896
67683b7e591a cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
   443
    def schema_relation(self): # XXX @property for consistency with meta
2126
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   444
        """return True if this relation type is used to build the schema"""
a25859917ccc stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   445
        return self.type in SCHEMA_TYPES
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   446
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   447
    def may_have_permission(self, action, req, eschema=None, role=None):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   448
        if eschema is not None:
4019
7f68077d2c3b api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4005
diff changeset
   449
            for tschema in self.targets(eschema, role):
7f68077d2c3b api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4005
diff changeset
   450
                rdef = self.role_rdef(eschema, tschema, role)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   451
                if rdef.may_have_permission(action, req):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   452
                    return True
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   453
        else:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   454
            for rdef in self.rdefs.itervalues():
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   455
                if rdef.may_have_permission(action, req):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   456
                    return True
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   457
        return False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   458
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   459
    def has_perm(self, session, action, **kwargs):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   460
        """return true if the action is granted globaly or localy"""
4575
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   461
        if self.final:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   462
            assert not ('fromeid' in kwargs or 'toeid' in kwargs), kwargs
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   463
            assert action in ('read', 'update')
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   464
            if 'eid' in kwargs:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   465
                subjtype = session.describe(kwargs['eid'])[0]
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   466
            else:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   467
                subjtype = objtype = None
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   468
        else:
4575
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   469
            assert not 'eid' in kwargs, kwargs
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   470
            assert action in ('read', 'add', 'delete')
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   471
            if 'fromeid' in kwargs:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   472
                subjtype = session.describe(kwargs['fromeid'])[0]
5746
f4fc424747db [security] SchemaRelation.has_perm grows to new arguments allowing to specify subject/object entity type when actual eid are not known, but their types are
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5703
diff changeset
   473
            elif 'frometype' in kwargs:
f4fc424747db [security] SchemaRelation.has_perm grows to new arguments allowing to specify subject/object entity type when actual eid are not known, but their types are
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5703
diff changeset
   474
                subjtype = kwargs.pop('frometype')
4575
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   475
            else:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   476
                subjtype = None
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   477
            if 'toeid' in kwargs:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   478
                objtype = session.describe(kwargs['toeid'])[0]
5746
f4fc424747db [security] SchemaRelation.has_perm grows to new arguments allowing to specify subject/object entity type when actual eid are not known, but their types are
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5703
diff changeset
   479
            elif 'toetype' in kwargs:
f4fc424747db [security] SchemaRelation.has_perm grows to new arguments allowing to specify subject/object entity type when actual eid are not known, but their types are
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5703
diff changeset
   480
                objtype = kwargs.pop('toetype')
4575
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   481
            else:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   482
                objtype = None
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   483
        if objtype and subjtype:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   484
            return self.rdef(subjtype, objtype).has_perm(session, action, **kwargs)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   485
        elif subjtype:
4004
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   486
            for tschema in self.targets(subjtype, 'subject'):
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   487
                rdef = self.rdef(subjtype, tschema)
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4037
diff changeset
   488
                if not rdef.has_perm(session, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   489
                    return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   490
        elif objtype:
4004
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   491
            for tschema in self.targets(objtype, 'object'):
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   492
                rdef = self.rdef(tschema, objtype)
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   493
                if not rdef.has_perm(session, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   494
                    return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   495
        else:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   496
            for rdef in self.rdefs.itervalues():
4004
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   497
                if not rdef.has_perm(session, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   498
                    return False
4233
94ffaecd8e8c ouch, has_perm was always returning False...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   499
        return True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   500
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   501
    @deprecated('use .rdef(subjtype, objtype).role_cardinality(role)')
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   502
    def cardinality(self, subjtype, objtype, target):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   503
        return self.rdef(subjtype, objtype).role_cardinality(target)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   504
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   505
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
class CubicWebSchema(Schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   507
    """set of entities and relations schema defining the possible data sets
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
    used in an application
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   509
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   510
    :type name: str
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2460
diff changeset
   511
    :ivar name: name of the schema, usually the instance identifier
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   512
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   513
    :type base: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   514
    :ivar base: path of the directory where the schema is defined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
    """
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   516
    reading_from_database = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   517
    entity_class = CubicWebEntitySchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
    relation_class = CubicWebRelationSchema
2958
44e5446b649b no inference for the identity relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2926
diff changeset
   519
    no_specialization_inference = ('identity',)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   521
    def __init__(self, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
        self._eid_index = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   523
        super(CubicWebSchema, self).__init__(*args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
        ybo.register_base_types(self)
2300
c8151d004e06 meta has been drop
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   525
        rschema = self.add_relation_type(ybo.RelationType('eid'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
        rschema.final = True
2300
c8151d004e06 meta has been drop
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   527
        rschema = self.add_relation_type(ybo.RelationType('has_text'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   528
        rschema.final = True
2300
c8151d004e06 meta has been drop
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   529
        rschema = self.add_relation_type(ybo.RelationType('identity'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   530
        rschema.final = False
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   531
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   532
    def add_entity_type(self, edef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   533
        edef.name = edef.name.encode()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   534
        edef.name = bw_normalize_etype(edef.name)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   535
        assert re.match(r'[A-Z][A-Za-z0-9]*[a-z]+[0-9]*$', edef.name), repr(edef.name)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   536
        eschema = super(CubicWebSchema, self).add_entity_type(edef)
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   537
        if not eschema.final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   538
            # automatically add the eid relation to non final entity types
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   539
            rdef = ybo.RelationDefinition(eschema.type, 'eid', 'Int',
4755
13a5d3a7410e [schema] tweaks meta-relations and schema/workflow entities attributes permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4754
diff changeset
   540
                                          cardinality='11', uid=True,
13a5d3a7410e [schema] tweaks meta-relations and schema/workflow entities attributes permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4754
diff changeset
   541
                                          __permissions__=RO_ATTR_PERMS)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   542
            self.add_relation_def(rdef)
4755
13a5d3a7410e [schema] tweaks meta-relations and schema/workflow entities attributes permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4754
diff changeset
   543
            rdef = ybo.RelationDefinition(eschema.type, 'identity', eschema.type,
13a5d3a7410e [schema] tweaks meta-relations and schema/workflow entities attributes permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4754
diff changeset
   544
                                          __permissions__=RO_REL_PERMS)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   545
            self.add_relation_def(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   546
        self._eid_index[eschema.eid] = eschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   547
        return eschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   548
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   549
    def add_relation_type(self, rdef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   550
        rdef.name = rdef.name.lower().encode()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   551
        rschema = super(CubicWebSchema, self).add_relation_type(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   552
        self._eid_index[rschema.eid] = rschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
        return rschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   554
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   555
    def add_relation_def(self, rdef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   556
        """build a part of a relation schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   557
        (i.e. add a relation between two specific entity's types)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   559
        :type subject: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   560
        :param subject: entity's type that is subject of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   561
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   562
        :type rtype: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
        :param rtype: the relation's type (i.e. the name of the relation)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   565
        :type obj: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
        :param obj: entity's type that is object of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
        :rtype: RelationSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   569
        :param: the newly created or just completed relation schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
        rdef.name = rdef.name.lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   572
        rdef.subject = bw_normalize_etype(rdef.subject)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   573
        rdef.object = bw_normalize_etype(rdef.object)
6191
ece6996e6ac8 [schema deserial] fix loading of schema when mapping an entity type to an existing one
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6109
diff changeset
   574
        rdefs = super(CubicWebSchema, self).add_relation_def(rdef)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   575
        if rdefs:
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   576
            try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   577
                self._eid_index[rdef.eid] = rdefs
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   578
            except AttributeError:
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   579
                pass # not a serialized schema
4003
b9436fe77c9e fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3998
diff changeset
   580
        return rdefs
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   581
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   582
    def del_relation_type(self, rtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   583
        rschema = self.rschema(rtype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   584
        self._eid_index.pop(rschema.eid, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   585
        super(CubicWebSchema, self).del_relation_type(rtype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   586
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   587
    def del_relation_def(self, subjtype, rtype, objtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   588
        for k, v in self._eid_index.items():
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   589
            if not isinstance(v, RelationDefinitionSchema):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   590
                continue
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   591
            if v.subject == subjtype and v.rtype == rtype and v.object == objtype:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
                del self._eid_index[k]
2718
3a56b87bb5d6 [schema] break when found
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2716
diff changeset
   593
                break
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   594
        super(CubicWebSchema, self).del_relation_def(subjtype, rtype, objtype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   595
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   596
    def del_entity_type(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
        eschema = self.eschema(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   598
        self._eid_index.pop(eschema.eid, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   599
        # deal with has_text first, else its automatic deletion (see above)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   600
        # may trigger an error in ancestor's del_entity_type method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   601
        if 'has_text' in eschema.subject_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   602
            self.del_relation_def(etype, 'has_text', 'String')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   603
        super(CubicWebSchema, self).del_entity_type(etype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   604
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   605
    def schema_by_eid(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   606
        return self._eid_index[eid]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   607
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   608
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   609
# Possible constraints ########################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   610
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   611
class BaseRQLConstraint(BaseConstraint):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   612
    """base class for rql constraints
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   613
    """
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   614
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   615
    def __init__(self, restriction, mainvars=None):
3963
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   616
        self.restriction = normalize_expression(restriction)
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   617
        if mainvars is None:
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   618
            mainvars = guess_rrqlexpr_mainvars(restriction)
3963
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   619
        else:
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   620
            normmainvars = []
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   621
            for mainvar in mainvars.split(','):
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   622
                mainvar = mainvar.strip()
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   623
                if not mainvar.isalpha():
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   624
                    raise Exception('bad mainvars %s' % mainvars)
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   625
                normmainvars.append(mainvar)
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   626
            assert mainvars, 'bad mainvars %s' % mainvars
0d592677e55f nicer mainvars/expression handling when initializing rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3961
diff changeset
   627
            mainvars = ','.join(sorted(normmainvars))
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   628
        self.mainvars = mainvars
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   629
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   630
    def serialize(self):
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   631
        # start with a comma for bw compat, see below
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   632
        return ';' + self.mainvars + ';' + self.restriction
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   633
5378
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
   634
    @classmethod
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   635
    def deserialize(cls, value):
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   636
        # XXX < 3.5.10 bw compat
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   637
        if not value.startswith(';'):
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   638
            return cls(value)
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   639
        _, mainvars, restriction = value.split(';', 2)
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   640
        return cls(restriction, mainvars)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   641
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   642
    def check(self, entity, rtype, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   643
        """return true if the value satisfy the constraint, else false"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   644
        # implemented as a hook in the repository
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   645
        return 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   646
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   647
    def repo_check(self, session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   648
        """raise ValidationError if the relation doesn't satisfy the constraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   649
        """
3554
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   650
        pass # this is a vocabulary constraint, not enforce XXX why?
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   651
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   652
    def __str__(self):
3965
94f95928f5ae nicer __str__ and __repr__ methods on rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3964
diff changeset
   653
        return '%s(Any %s WHERE %s)' % (self.__class__.__name__, self.mainvars,
94f95928f5ae nicer __str__ and __repr__ methods on rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3964
diff changeset
   654
                                        self.restriction)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   655
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   656
    def __repr__(self):
3965
94f95928f5ae nicer __str__ and __repr__ methods on rql constraints
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3964
diff changeset
   657
        return '<%s @%#x>' % (self.__str__(), id(self))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   658
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   659
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   660
class RQLVocabularyConstraint(BaseRQLConstraint):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   661
    """the rql vocabulary constraint :
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   662
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   663
    limit the proposed values to a set of entities returned by a rql query,
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   664
    but this is not enforced at the repository level
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   665
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   666
     restriction is additional rql restriction that will be added to
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   667
     a predefined query, where the S and O variables respectivly represent
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   668
     the subject and the object of the relation
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   669
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   670
     mainvars is a string that should be used as selection variable (eg
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   671
     `'Any %s WHERE ...' % mainvars`). If not specified, an attempt will be
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   672
     done to guess it according to variable used in the expression.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   673
    """
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   674
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   675
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   676
class RepoEnforcedRQLConstraintMixIn(object):
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   677
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   678
    def __init__(self, restriction, mainvars=None, msg=None):
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   679
        super(RepoEnforcedRQLConstraintMixIn, self).__init__(restriction, mainvars)
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   680
        self.msg = msg
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   681
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   682
    def serialize(self):
3968
e8dbad65a7a2 fix format string
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3967
diff changeset
   683
        # start with a semicolon for bw compat, see below
e8dbad65a7a2 fix format string
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3967
diff changeset
   684
        return ';%s;%s\n%s' % (self.mainvars, self.restriction,
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   685
                               self.msg or '')
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   686
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   687
    def deserialize(cls, value):
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   688
        # XXX < 3.5.10 bw compat
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   689
        if not value.startswith(';'):
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   690
            return cls(value)
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   691
        value, msg = value.split('\n', 1)
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   692
        _, mainvars, restriction = value.split(';', 2)
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   693
        return cls(restriction, mainvars, msg)
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   694
    deserialize = classmethod(deserialize)
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   695
3554
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3347
diff changeset
   696
    def repo_check(self, session, eidfrom, rtype, eidto=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   697
        """raise ValidationError if the relation doesn't satisfy the constraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   698
        """
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   699
        if not self.match_condition(session, eidfrom, eidto):
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   700
            # XXX at this point if both or neither of S and O are in mainvar we
6109
47d9c0e0f7b7 integrate Celso's work on translation file: proper/complete spanish translation, fixed some typos in french translation, occured -> occurred fix in various places
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6017
diff changeset
   701
            # dunno if the validation error `occurred` on eidfrom or eidto (from
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   702
            # user interface point of view)
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
   703
            #
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
   704
            # possible enhancement: check entity being created, it's probably
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
   705
            # the main eid unless this is a composite relation
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   706
            if eidto is None or 'S' in self.mainvars or not 'O' in self.mainvars:
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   707
                maineid = eidfrom
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
   708
                qname = role_name(rtype, 'subject')
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   709
            else:
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   710
                maineid = eidto
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
   711
                qname = role_name(rtype, 'object')
3964
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   712
            if self.msg:
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   713
                msg = session._(self.msg)
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   714
            else:
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   715
                msg = '%(constraint)s %(restriction)s failed' % {
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   716
                    'constraint':  session._(self.type()),
21387ffb0731 refactor so that we can specify an extra argument to constraints which
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3963
diff changeset
   717
                    'restriction': self.restriction}
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4913
diff changeset
   718
            raise ValidationError(maineid, {qname: msg})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   719
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   720
    def exec_query(self, session, eidfrom, eidto):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   721
        if eidto is None:
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   722
            # checking constraint for an attribute relation
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   723
            restriction = 'S eid %(s)s, ' + self.restriction
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
   724
            args = {'s': eidfrom}
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   725
        else:
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   726
            restriction = 'S eid %(s)s, O eid %(o)s, ' + self.restriction
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
   727
            args = {'s': eidfrom, 'o': eidto}
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   728
        rql = 'Any %s WHERE %s' % (self.mainvars,  restriction)
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   729
        if self.distinct_query:
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   730
            rql = 'DISTINCT ' + rql
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
   731
        return session.execute(rql, args, build_descr=False)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   732
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   733
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   734
class RQLConstraint(RepoEnforcedRQLConstraintMixIn, RQLVocabularyConstraint):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   735
    """the rql constraint is similar to the RQLVocabularyConstraint but
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   736
    are also enforced at the repository level
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   737
    """
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   738
    distinct_query = False
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   739
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   740
    def match_condition(self, session, eidfrom, eidto):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   741
        return self.exec_query(session, eidfrom, eidto)
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   742
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   743
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   744
class RQLUniqueConstraint(RepoEnforcedRQLConstraintMixIn, BaseRQLConstraint):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   745
    """the unique rql constraint check that the result of the query isn't
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   746
    greater than one
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   747
    """
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   748
    distinct_query = True
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   749
3985
d5bf894fcf02 add some notes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3980
diff changeset
   750
    # XXX turns mainvars into a required argument in __init__, since we've no
d5bf894fcf02 add some notes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3980
diff changeset
   751
    #     way to guess it correctly (eg if using S,O or U the constraint will
d5bf894fcf02 add some notes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3980
diff changeset
   752
    #     always be satisfied since we've to use a DISTINCT query)
d5bf894fcf02 add some notes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3980
diff changeset
   753
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   754
    def match_condition(self, session, eidfrom, eidto):
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   755
        return len(self.exec_query(session, eidfrom, eidto)) <= 1
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   756
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   757
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   758
class RQLExpression(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   759
    def __init__(self, expression, mainvars, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   760
        self.eid = eid # eid of the entity representing this rql expression
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   761
        if not isinstance(mainvars, unicode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   762
            mainvars = unicode(mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   763
        self.mainvars = mainvars
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   764
        self.expression = normalize_expression(expression)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   765
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   766
            self.rqlst = parse(self.full_rql, print_errors=False).children[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   767
        except RQLSyntaxError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   768
            raise RQLSyntaxError(expression)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   769
        for mainvar in mainvars.split(','):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   770
            if len(self.rqlst.defined_vars[mainvar].references()) <= 2:
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   771
                _LOGGER.warn('You did not use the %s variable in your RQL '
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   772
                             'expression %s', mainvar, self)
3825
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3824
diff changeset
   773
        # syntax tree used by read security (inserted in queries when necessary)
3240
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2967
diff changeset
   774
        self.snippet_rqlst = parse(self.minimal_rql, print_errors=False).children[0]
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   775
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   776
    def __str__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   777
        return self.full_rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   778
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   779
        return '%s(%s)' % (self.__class__.__name__, self.full_rql)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   780
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   781
    def __cmp__(self, other):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   782
        if hasattr(other, 'expression'):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   783
            return cmp(other.expression, self.expression)
4066
0555f170c4d1 __cmp__ should *NOT* return False when different
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4045
diff changeset
   784
        return -1
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   785
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   786
    def __deepcopy__(self, memo):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   787
        return self.__class__(self.expression, self.mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   788
    def __getstate__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   789
        return (self.expression, self.mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   790
    def __setstate__(self, state):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   791
        self.__init__(*state)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   792
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   793
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   794
    def transform_has_permission(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   795
        found = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   796
        rqlst = self.rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   797
        for var in rqlst.defined_vars.itervalues():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   798
            for varref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   799
                rel = varref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   800
                if rel is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   801
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   802
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   803
                    prefix, action, suffix = rel.r_type.split('_')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   804
                except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   805
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   806
                if prefix != 'has' or suffix != 'permission' or \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   807
                       not action in ('add', 'delete', 'update', 'read'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   808
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   809
                if found is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   810
                    found = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   811
                    rqlst.save_state()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   812
                assert rel.children[0].name == 'U'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   813
                objvar = rel.children[1].children[0].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   814
                rqlst.remove_node(rel)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   815
                selected = [v.name for v in rqlst.get_selected_variables()]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   816
                if objvar.name not in selected:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   817
                    colindex = len(selected)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   818
                    rqlst.add_selected(objvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   819
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   820
                    colindex = selected.index(objvar.name)
4717
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
   821
                found.append((action, colindex))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   822
                # remove U eid %(u)s if U is not used in any other relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   823
                uvrefs = rqlst.defined_vars['U'].references()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   824
                if len(uvrefs) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   825
                    rqlst.remove_node(uvrefs[0].relation())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   826
        if found is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   827
            rql = rqlst.as_string()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   828
            if len(rqlst.selection) == 1 and isinstance(rqlst.where, nodes.Relation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   829
                # only "Any X WHERE X eid %(x)s" remaining, no need to execute the rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   830
                keyarg = rqlst.selection[0].name.lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   831
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   832
                keyarg = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   833
            rqlst.recover()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   834
            return rql, found, keyarg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   835
        return rqlst.as_string(), None, None
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   836
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   837
    def _check(self, session, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   838
        """return True if the rql expression is matching the given relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   839
        between fromeid and toeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   840
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   841
        session may actually be a request as well
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   842
        """
4607
55eab66c6592 [schema security] fix so that when cheking attributes perms for an entity being created, 'owners' and has_*_permission in erqlexpr are considered satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4586
diff changeset
   843
        creating = kwargs.get('creating')
55eab66c6592 [schema security] fix so that when cheking attributes perms for an entity being created, 'owners' and has_*_permission in erqlexpr are considered satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4586
diff changeset
   844
        if not creating and self.eid is not None:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   845
            key = (self.eid, tuple(sorted(kwargs.iteritems())))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   846
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   847
                return session.local_perm_cache[key]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   848
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   849
                pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   850
        rql, has_perm_defs, keyarg = self.transform_has_permission()
5703
24ca7615379b [security] consider any rql expression refering to X while X is being created as satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5531
diff changeset
   851
        # when creating an entity, expression related to X satisfied
24ca7615379b [security] consider any rql expression refering to X while X is being created as satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5531
diff changeset
   852
        if creating and 'X' in self.rqlst.defined_vars:
24ca7615379b [security] consider any rql expression refering to X while X is being created as satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5531
diff changeset
   853
            return True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   854
        if keyarg is None:
4619
f4254586e867 [security] allow to call .check on rql expression with a user eid specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4608
diff changeset
   855
            kwargs.setdefault('u', session.user.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   856
            try:
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5122
diff changeset
   857
                rset = session.execute(rql, kwargs, build_descr=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   858
            except NotImplementedError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   859
                self.critical('cant check rql expression, unsupported rql %s', rql)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   860
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   861
                    session.local_perm_cache[key] = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   862
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   863
            except TypeResolverException, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   864
                # some expression may not be resolvable with current kwargs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   865
                # (type conflict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   866
                self.warning('%s: %s', rql, str(ex))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   867
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   868
                    session.local_perm_cache[key] = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   869
                return False
5531
0ce62ac0d1d7 catch unauthorized when executing rql to check an rql expression. Fix #968824
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   870
            except Unauthorized, ex:
0ce62ac0d1d7 catch unauthorized when executing rql to check an rql expression. Fix #968824
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   871
                self.debug('unauthorized %s: %s', rql, str(ex))
0ce62ac0d1d7 catch unauthorized when executing rql to check an rql expression. Fix #968824
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   872
                if self.eid is not None:
0ce62ac0d1d7 catch unauthorized when executing rql to check an rql expression. Fix #968824
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   873
                    session.local_perm_cache[key] = False
0ce62ac0d1d7 catch unauthorized when executing rql to check an rql expression. Fix #968824
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   874
                return False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   875
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   876
            rset = session.eid_rset(kwargs[keyarg])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   877
        # if no special has_*_permission relation in the rql expression, just
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   878
        # check the result set contains something
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   879
        if has_perm_defs is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   880
            if rset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   881
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   882
                    session.local_perm_cache[key] = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   883
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   884
        elif rset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   885
            # check every special has_*_permission relation is satisfied
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   886
            get_eschema = session.vreg.schema.eschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   887
            try:
4717
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
   888
                for eaction, col in has_perm_defs:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   889
                    for i in xrange(len(rset)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   890
                        eschema = get_eschema(rset.description[i][col])
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   891
                        eschema.check_perm(session, eaction, eid=rset[i][col])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   892
                if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   893
                    session.local_perm_cache[key] = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   894
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   895
            except Unauthorized:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   896
                pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   897
        if self.eid is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   898
            session.local_perm_cache[key] = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   899
        return False
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   900
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   901
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   902
    def minimal_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   903
        return 'Any %s WHERE %s' % (self.mainvars, self.expression)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   904
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   905
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   906
class ERQLExpression(RQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   907
    def __init__(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   908
        RQLExpression.__init__(self, expression, mainvars or 'X', eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   909
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   910
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   911
    def full_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   912
        rql = self.minimal_rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   913
        rqlst = getattr(self, 'rqlst', None) # may be not set yet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   914
        if rqlst is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   915
            defined = rqlst.defined_vars
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   916
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   917
            defined = set(split_expression(self.expression))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   918
        if 'X' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   919
            rql += ', X eid %(x)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   920
        if 'U' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   921
            rql += ', U eid %(u)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   922
        return rql
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   923
4619
f4254586e867 [security] allow to call .check on rql expression with a user eid specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4608
diff changeset
   924
    def check(self, session, eid=None, creating=False, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   925
        if 'X' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   926
            if eid is None:
4607
55eab66c6592 [schema security] fix so that when cheking attributes perms for an entity being created, 'owners' and has_*_permission in erqlexpr are considered satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4586
diff changeset
   927
                if creating:
4619
f4254586e867 [security] allow to call .check on rql expression with a user eid specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4608
diff changeset
   928
                    return self._check(session, creating=True, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   929
                return False
4607
55eab66c6592 [schema security] fix so that when cheking attributes perms for an entity being created, 'owners' and has_*_permission in erqlexpr are considered satisfied
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4586
diff changeset
   930
            assert creating == False
4619
f4254586e867 [security] allow to call .check on rql expression with a user eid specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4608
diff changeset
   931
            return self._check(session, x=eid, **kwargs)
f4254586e867 [security] allow to call .check on rql expression with a user eid specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4608
diff changeset
   932
        return self._check(session, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   933
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   934
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   935
class RRQLExpression(RQLExpression):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   936
    def __init__(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   937
        if mainvars is None:
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   938
            mainvars = guess_rrqlexpr_mainvars(expression)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   939
        RQLExpression.__init__(self, expression, mainvars, eid)
3827
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3826
diff changeset
   940
        # graph of links between variable, used by rql rewriter
3826
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   941
        self.vargraph = {}
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   942
        for relation in self.rqlst.get_nodes(nodes.Relation):
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   943
            try:
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   944
                rhsvarname = relation.children[1].children[0].variable.name
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   945
                lhsvarname = relation.children[0].name
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   946
            except AttributeError:
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   947
                pass
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   948
            else:
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   949
                self.vargraph.setdefault(lhsvarname, []).append(rhsvarname)
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   950
                self.vargraph.setdefault(rhsvarname, []).append(lhsvarname)
0c0c051863cb close #511810: bad rql generated when looking for vocabulary for a relation on an entity which doesn't exist (yet)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3825
diff changeset
   951
                #self.vargraph[(lhsvarname, rhsvarname)] = relation.r_type
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   952
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   953
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   954
    def full_rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   955
        rql = self.minimal_rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   956
        rqlst = getattr(self, 'rqlst', None) # may be not set yet
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   957
        if rqlst is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   958
            defined = rqlst.defined_vars
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   959
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   960
            defined = set(split_expression(self.expression))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   961
        if 'S' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   962
            rql += ', S eid %(s)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   963
        if 'O' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   964
            rql += ', O eid %(o)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   965
        if 'U' in defined:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   966
            rql += ', U eid %(u)s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   967
        return rql
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   968
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   969
    def check(self, session, fromeid=None, toeid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   970
        kwargs = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   971
        if 'S' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   972
            if fromeid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   973
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   974
            kwargs['s'] = fromeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   975
        if 'O' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   976
            if toeid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   977
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   978
            kwargs['o'] = toeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   979
        return self._check(session, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   980
4570
ede247bbbf62 follow yams api change: attributes permissions are now defined for
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   981
# in yams, default 'update' perm for attributes granted to managers and owners.
ede247bbbf62 follow yams api change: attributes permissions are now defined for
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   982
# Within cw, we want to default to users who may edit the entity holding the
ede247bbbf62 follow yams api change: attributes permissions are now defined for
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   983
# attribute.
4586
440e340c61fe DEFAULT_ATTRPERMS is now public
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4575
diff changeset
   984
ybo.DEFAULT_ATTRPERMS['update'] = (
4570
ede247bbbf62 follow yams api change: attributes permissions are now defined for
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   985
    'managers', ERQLExpression('U has_update_permission X'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   986
629
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   987
# workflow extensions #########################################################
2926
4484387ed012 when adding/removing cubes, we should add/remove entity types in correct order if one inherits from another
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   988
2460
ce1a7ffc6c90 fix a couple NameErrors
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2459
diff changeset
   989
from yams.buildobjs import _add_relation as yams_add_relation
629
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   990
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   991
class workflowable_definition(ybo.metadefinition):
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   992
    """extends default EntityType's metaclass to add workflow relations
5378
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
   993
    (i.e. in_state, wf_info_for and custom_workflow). This is the default
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
   994
    metaclass for WorkflowableEntityType.
629
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   995
    """
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
   996
    def __new__(mcs, name, bases, classdict):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   997
        abstract = classdict.pop('__abstract__', False)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   998
        cls = super(workflowable_definition, mcs).__new__(mcs, name, bases,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
   999
                                                          classdict)
629
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
  1000
        if not abstract:
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1001
            make_workflowable(cls)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1002
        return cls
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1003
5379
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1004
class WorkflowableEntityType(ybo.EntityType):
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1005
    """Use this base class instead of :class:`EntityType` to have workflow
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1006
    relations (i.e. `in_state`, `wf_info_for` and `custom_workflow`) on your
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1007
    entity type.
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1008
    """
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1009
    __metaclass__ = workflowable_definition
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1010
    __abstract__ = True
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1011
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1012
2957
2daabf4c646e [schema] make_workflowable now take an option description for the in_state relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2931
diff changeset
  1013
def make_workflowable(cls, in_state_descr=None):
5378
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
  1014
    """Adds workflow relations as :class:`WorkflowableEntityType`, but usable on
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
  1015
    existing classes which are not using that base class.
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
  1016
    """
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1017
    existing_rels = set(rdef.name for rdef in cls.__relations__)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1018
    # let relation types defined in cw.schemas.workflow carrying
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1019
    # cardinality, constraints and other relation definition properties
5379
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1020
    etype = getattr(cls, 'name', cls.__name__)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1021
    if 'custom_workflow' not in existing_rels:
5379
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1022
        rdef = ybo.RelationDefinition(etype, 'custom_workflow', 'Workflow')
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1023
        yams_add_relation(cls.__relations__, rdef)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1024
    if 'in_state' not in existing_rels:
5379
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1025
        rdef = ybo.RelationDefinition(etype, 'in_state', 'State',
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1026
                                      description=in_state_descr)
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1027
        yams_add_relation(cls.__relations__, rdef)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1028
    if 'wf_info_for' not in existing_rels:
5379
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1029
        rdef = ybo.RelationDefinition('TrInfo', 'wf_info_for', etype)
c082dea0731b [schema] update for yams 0.29: BoundConstraint renamed to BoundaryConstraint; new constraint messages; ObjectRelation deprecated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5378
diff changeset
  1030
        yams_add_relation(cls.__relations__, rdef)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1031
629
59b6542f5729 provide a new WorkflowableEntityType base class (will be refactored later, maybe with schema interfaces)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 628
diff changeset
  1032
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1033
# schema loading ##############################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1034
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1035
CONSTRAINTS['RQLConstraint'] = RQLConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1036
CONSTRAINTS['RQLUniqueConstraint'] = RQLUniqueConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1037
CONSTRAINTS['RQLVocabularyConstraint'] = RQLVocabularyConstraint
3980
b17cf4a2e09e this constraint is actually unusable in yams schema for cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3979
diff changeset
  1038
CONSTRAINTS.pop('MultipleStaticVocabularyConstraint', None) # don't want this in cw yams schema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1039
PyFileReader.context.update(CONSTRAINTS)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1040
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1041
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1042
class BootstrapSchemaLoader(SchemaLoader):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1043
    """cubicweb specific schema loader, loading only schema necessary to read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1044
    the persistent schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1045
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1046
    schemacls = CubicWebSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1047
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
  1048
    def load(self, config, path=(), **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1049
        """return a Schema instance from the schema definition read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1050
        from <directory>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1051
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1052
        return super(BootstrapSchemaLoader, self).load(
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
  1053
            path, config.appid, register_base_types=False, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1054
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1055
    def _load_definition_files(self, cubes=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1056
        # bootstraping, ignore cubes
2735
39c942241b48 no need for lib_directory
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2730
diff changeset
  1057
        filepath = join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'bootstrap.py')
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
  1058
        self.info('loading %s', filepath)
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
  1059
        self.handle_file(filepath)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1060
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1061
    def unhandled_file(self, filepath):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1062
        """called when a file without handler associated has been found"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1063
        self.warning('ignoring file %r', filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1064
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1065
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1066
class CubicWebSchemaLoader(BootstrapSchemaLoader):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1067
    """cubicweb specific schema loader, automatically adding metadata to the
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2460
diff changeset
  1068
    instance's schema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1069
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1070
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
  1071
    def load(self, config, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1072
        """return a Schema instance from the schema definition read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1073
        from <directory>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1074
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1075
        self.info('loading %s schemas', ', '.join(config.cubes()))
2782
998f24dabd0d compute extrapath, necessary for proper schema module detection when CW_CUBES_PATH is set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2742
diff changeset
  1076
        self.extrapath = {}
998f24dabd0d compute extrapath, necessary for proper schema module detection when CW_CUBES_PATH is set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2742
diff changeset
  1077
        for cubesdir in config.cubes_search_path():
998f24dabd0d compute extrapath, necessary for proper schema module detection when CW_CUBES_PATH is set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2742
diff changeset
  1078
            if cubesdir != config.CUBES_DIR:
998f24dabd0d compute extrapath, necessary for proper schema module detection when CW_CUBES_PATH is set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2742
diff changeset
  1079
                self.extrapath[cubesdir] = 'cubes'
372
a8a975a88368 check apphome is not None
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
  1080
        if config.apphome:
2598
a66fe74bd9fc [R schema] dont give an iterator, it's a trap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2596
diff changeset
  1081
            path = tuple(reversed([config.apphome] + config.cubes_path()))
372
a8a975a88368 check apphome is not None
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
  1082
        else:
2598
a66fe74bd9fc [R schema] dont give an iterator, it's a trap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2596
diff changeset
  1083
            path = tuple(reversed(config.cubes_path()))
2526
40e41eb34a7d we've to call cleanup_sys_modules manually for proper schema modules cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
  1084
        try:
40e41eb34a7d we've to call cleanup_sys_modules manually for proper schema modules cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
  1085
            return super(CubicWebSchemaLoader, self).load(config, path=path, **kwargs)
40e41eb34a7d we've to call cleanup_sys_modules manually for proper schema modules cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
  1086
        finally:
40e41eb34a7d we've to call cleanup_sys_modules manually for proper schema modules cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2476
diff changeset
  1087
            # we've to cleanup modules imported from cubicweb.schemas as well
2735
39c942241b48 no need for lib_directory
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2730
diff changeset
  1088
            cleanup_sys_modules([join(cubicweb.CW_SOFTWARE_ROOT, 'schemas')])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1089
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1090
    def _load_definition_files(self, cubes):
2741
148d0cea1fb5 [schema] oops
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2736
diff changeset
  1091
        for filepath in (join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'bootstrap.py'),
148d0cea1fb5 [schema] oops
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2736
diff changeset
  1092
                         join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'base.py'),
148d0cea1fb5 [schema] oops
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2736
diff changeset
  1093
                         join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'workflow.py'),
148d0cea1fb5 [schema] oops
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2736
diff changeset
  1094
                         join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'Bookmark.py')):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1095
            self.info('loading %s', filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1096
            self.handle_file(filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1097
        for cube in cubes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1098
            for filepath in self.get_schema_files(cube):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1099
                self.info('loading %s', filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1100
                self.handle_file(filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1101
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1102
2459
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2456
diff changeset
  1103
set_log_methods(CubicWebSchemaLoader, getLogger('cubicweb.schemaloader'))
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2456
diff changeset
  1104
set_log_methods(BootstrapSchemaLoader, getLogger('cubicweb.bootstrapschemaloader'))
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2456
diff changeset
  1105
set_log_methods(RQLExpression, getLogger('cubicweb.schema'))
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2456
diff changeset
  1106
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1107
# _() is just there to add messages to the catalog, don't care about actual
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1108
# translation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1109
PERM_USE_TEMPLATE_FORMAT = _('use_template_format')
2459
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2456
diff changeset
  1110
NEED_PERM_FORMATS = [_('text/cubicweb-page-template')]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1111
2531
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
  1112
@monkeypatch(FormatConstraint)
3347
428f95118556 fix vocab param to avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3287
diff changeset
  1113
def vocabulary(self, entity=None, form=None):
3401
f893f4f199fc use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
  1114
    cw = None
3347
428f95118556 fix vocab param to avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3287
diff changeset
  1115
    if form is None and entity is not None:
3401
f893f4f199fc use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
  1116
        cw = entity._cw
3347
428f95118556 fix vocab param to avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3287
diff changeset
  1117
    elif form is not None:
3401
f893f4f199fc use ._cw instead of req on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3369
diff changeset
  1118
        cw = form._cw
4757
5d937aeaa6fb do not check for use template permission when session is super session or integrity hooks are deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4755
diff changeset
  1119
    if cw is not None:
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
  1120
        if hasattr(cw, 'write_security'): # test it's a session and not a request
4757
5d937aeaa6fb do not check for use template permission when session is super session or integrity hooks are deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4755
diff changeset
  1121
            # cw is a server session
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
  1122
            hasperm = not cw.write_security or \
4843
5f7363416765 fix hooks control method name + other litle cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
  1123
                      not cw.is_hook_category_activated('integrity') or \
4757
5d937aeaa6fb do not check for use template permission when session is super session or integrity hooks are deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4755
diff changeset
  1124
                      cw.user.has_permission(PERM_USE_TEMPLATE_FORMAT)
5d937aeaa6fb do not check for use template permission when session is super session or integrity hooks are deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4755
diff changeset
  1125
        else:
5d937aeaa6fb do not check for use template permission when session is super session or integrity hooks are deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4755
diff changeset
  1126
            hasperm = cw.user.has_permission(PERM_USE_TEMPLATE_FORMAT)
5d937aeaa6fb do not check for use template permission when session is super session or integrity hooks are deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4755
diff changeset
  1127
        if hasperm:
5d937aeaa6fb do not check for use template permission when session is super session or integrity hooks are deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4755
diff changeset
  1128
            return self.regular_formats + tuple(NEED_PERM_FORMATS)
2459
d088d0ff48a1 move RichString and co to yams, keeping only a small monkeypatch for cw-page-template here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2456
diff changeset
  1129
    return self.regular_formats
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1130
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1131
# XXX monkey patch PyFileReader.import_erschema until bw_normalize_etype is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1132
# necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1133
orig_import_erschema = PyFileReader.import_erschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1134
def bw_import_erschema(self, ertype, schemamod=None, instantiate=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1135
    return orig_import_erschema(self, bw_normalize_etype(ertype), schemamod, instantiate)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1136
PyFileReader.import_erschema = bw_import_erschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1137
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1138
# XXX itou for some Statement methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1139
from rql import stmts
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1140
orig_get_etype = stmts.ScopeNode.get_etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1141
def bw_get_etype(self, name):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1142
    return orig_get_etype(self, bw_normalize_etype(name))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1143
stmts.ScopeNode.get_etype = bw_get_etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1144
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1145
orig_add_main_variable_delete = stmts.Delete.add_main_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1146
def bw_add_main_variable_delete(self, etype, vref):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1147
    return orig_add_main_variable_delete(self, bw_normalize_etype(etype), vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1148
stmts.Delete.add_main_variable = bw_add_main_variable_delete
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1149
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1150
orig_add_main_variable_insert = stmts.Insert.add_main_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1151
def bw_add_main_variable_insert(self, etype, vref):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1152
    return orig_add_main_variable_insert(self, bw_normalize_etype(etype), vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1153
stmts.Insert.add_main_variable = bw_add_main_variable_insert
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1154
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1155
orig_set_statement_type = stmts.Select.set_statement_type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1156
def bw_set_statement_type(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1157
    return orig_set_statement_type(self, bw_normalize_etype(etype))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1158
stmts.Select.set_statement_type = bw_set_statement_type
2736
c5048502409f restore backward compat, still imported a lot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2735
diff changeset
  1159
c5048502409f restore backward compat, still imported a lot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2735
diff changeset
  1160
# XXX deprecated
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1161
2736
c5048502409f restore backward compat, still imported a lot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2735
diff changeset
  1162
from yams.buildobjs import RichString
4717
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
  1163
from yams.constraints import StaticVocabularyConstraint
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
  1164
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
  1165
RichString = class_moved(RichString)
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
  1166
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
  1167
StaticVocabularyConstraint = class_moved(StaticVocabularyConstraint)
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
  1168
FormatConstraint = class_moved(FormatConstraint)
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1169
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1170
PyFileReader.context['ERQLExpression'] = yobsolete(ERQLExpression)
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1171
PyFileReader.context['RRQLExpression'] = yobsolete(RRQLExpression)
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1172
PyFileReader.context['WorkflowableEntityType'] = WorkflowableEntityType