schema.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 07 Jan 2014 16:19:18 +0100
changeset 9366 bcbc92223b35
parent 9283 5f2c5eb1a820
child 9393 8266c8c375bb
permissions -rw-r--r--
set proper PACKAGE information for yams 0.39 Yams 0.39 adds an unobstrusive API to get the package, or cube, defining a part of the schema (entity type, relation type/def). As CubicWeb overrides part of the schema reading process, we have to handle this information on our side so it will be properly set.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8945
ba9e3fbfa5a5 [schemaserial] serialize additional yams parameter for customs type
Vincent Michel <vincent.michel@logilab.fr>
parents: 8892
diff changeset
     1
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
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
     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
9366
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
    24
from os.path import join, basename
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
9366
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
    28
from logilab.common import tempattr
9280
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
    29
from logilab.common.decorators import cached, clear_cache, monkeypatch, cachedproperty
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
    30
from logilab.common.logging_ext import set_log_methods
8256
852c73392b00 [schema] make cubicweb 3.14 compatible with yams 0.35
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8160
diff changeset
    31
from logilab.common.deprecation import deprecated, class_moved, moved
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
    32
from logilab.common.textutils import splitstrip
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
    33
from logilab.common.graph import get_cycles
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
from logilab.common.compat import any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
2531
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
    36
from yams import BadSchemaDefinition, buildobjs as ybo
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
    37
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
    38
     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
    39
from yams.constraints import BaseConstraint, FormatConstraint
2531
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
    40
from yams.reader import (CONSTRAINTS, PyFileReader, SchemaLoader,
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
    41
                         obsolete as yobsolete, cleanup_sys_modules)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
from rql import parse, nodes, RQLSyntaxError, TypeResolverException
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
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
    45
import cubicweb
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
9148
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    48
try:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    49
    from cubicweb import server
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    50
except ImportError:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    51
    # We need to lookup DEBUG from there,
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    52
    # however a pure dbapi client may not have it.
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    53
    class server(object): pass
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    54
    server.DEBUG = False
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    55
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
    56
2596
d02eed70937f [R repo, schema] use VIRTUAL_RTYPES const
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2531
diff changeset
    57
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
    58
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
    59
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4843
diff changeset
    60
# 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
    61
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
    62
    'owned_by', 'created_by', 'is', 'is_instance_of', 'identity',
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6377
diff changeset
    63
    'eid', 'creation_date', 'cw_source', 'modification_date', 'has_text', 'cwuri',
2184
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2181
diff changeset
    64
    ))
6375
df4fd2a1b0e7 [schema] introduce new WORKFLOW_RTYPES set and use it to build SYSTEM_RTYPES/DONT_CHECK_RTYPES_ON_ADD/DONT_CHECK_RTYPES_ON_DEL sets
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6262
diff changeset
    65
WORKFLOW_RTYPES = set(('custom_workflow', 'in_state', 'wf_info_for'))
6377
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    66
WORKFLOW_DEF_RTYPES = set(('workflow_of', 'state_of', 'transition_of',
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    67
                           'initial_state', 'default_workflow',
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    68
                           'allowed_transition', 'destination_state',
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    69
                           'from_state', 'to_state', 'condition',
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    70
                           'subworkflow', 'subworkflow_state', 'subworkflow_exit',
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    71
                           ))
7797
a71618a75b53 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7782
diff changeset
    72
SYSTEM_RTYPES = set(('in_group', 'require_group',
6377
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    73
                     # cwproperty
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    74
                     'for_user',
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    75
                     )) | WORKFLOW_RTYPES
6481
103774c8c215 [schema categorization] new NO_I18NCONTEXT set usable to somewhat control c-c i18n
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6427
diff changeset
    76
NO_I18NCONTEXT = META_RTYPES | WORKFLOW_RTYPES
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
6951
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
    78
SKIP_COMPOSITE_RELS = [('cw_source', 'subject')]
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
    79
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4843
diff changeset
    80
# 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
    81
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
    82
    'CWEType', 'CWRType', 'CWAttribute', 'CWRelation',
6229
c4a70a5dd144 [schema] mark CWUniqueTogetherConstraint and its relations as schema entity/relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6191
diff changeset
    83
    'CWConstraint', 'CWConstraintType', 'CWUniqueTogetherConstraint',
c4a70a5dd144 [schema] mark CWUniqueTogetherConstraint and its relations as schema entity/relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6191
diff changeset
    84
    'RQLExpression',
6377
3bb415310d4f [schema] introduce some new sets categorizing entity/relation types and benefits from them where possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6375
diff changeset
    85
    'specializes',
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
    86
    '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
    87
    'constrained_by', 'cstrtype',
6229
c4a70a5dd144 [schema] mark CWUniqueTogetherConstraint and its relations as schema entity/relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6191
diff changeset
    88
    'constraint_of', 'relations',
6262
84901d735156 add permission relations to schema types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6233
diff changeset
    89
    'read_permission', 'add_permission',
84901d735156 add permission relations to schema types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6233
diff changeset
    90
    'delete_permission', 'update_permission',
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
    91
    ))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
4434
101344a6ff9b Improve the schema command with filtering option.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4252
diff changeset
    93
WORKFLOW_TYPES = set(('Transition', 'State', 'TrInfo', 'Workflow',
4759
af2e6c377c71 cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4757
diff changeset
    94
                      'WorkflowTransition', 'BaseTransition',
af2e6c377c71 cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4757
diff changeset
    95
                      'SubWorkflowExitPoint'))
af2e6c377c71 cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4757
diff changeset
    96
9173
f3286e817f28 [schema] mark CWDataImport as an internal type. Closes #3025536
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9168
diff changeset
    97
INTERNAL_TYPES = set(('CWProperty', 'CWCache', 'ExternalUri', 'CWDataImport',
6949
267ce7cf77f1 [test, ui] mark CWSourceSchemaConfig as an internal type
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6944
diff changeset
    98
                      'CWSource', 'CWSourceHostConfig', 'CWSourceSchemaConfig'))
4434
101344a6ff9b Improve the schema command with filtering option.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4252
diff changeset
    99
101344a6ff9b Improve the schema command with filtering option.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 4252
diff changeset
   100
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   101
_LOGGER = getLogger('cubicweb.schemaloader')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
8945
ba9e3fbfa5a5 [schemaserial] serialize additional yams parameter for customs type
Vincent Michel <vincent.michel@logilab.fr>
parents: 8892
diff changeset
   103
# entity and relation schema created from serialized schema have an eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
ybo.ETYPE_PROPERTIES += ('eid',)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
ybo.RTYPE_PROPERTIES += ('eid',)
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
   106
4754
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   107
PUB_SYSTEM_ENTITY_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   108
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   109
    'add':    ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   110
    'delete': ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   111
    'update': ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   112
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   113
PUB_SYSTEM_REL_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   114
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   115
    'add':    ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   116
    'delete': ('managers',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   117
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   118
PUB_SYSTEM_ATTR_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   119
    'read':   ('managers', 'users', 'guests',),
6944
0cf10429ad39 [sources] rewrite the way pyrorql mapping are stored in the database so it can be reused for other sources (eg datafeed+cwxml)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6861
diff changeset
   120
    'update': ('managers',),
4754
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   121
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   122
RO_REL_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   123
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   124
    'add':    (),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   125
    'delete': (),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   126
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   127
RO_ATTR_PERMS = {
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   128
    'read':   ('managers', 'users', 'guests',),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   129
    'update': (),
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   130
    }
6bf17f810975 [schema] new constants for permissions definitions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4717
diff changeset
   131
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
   132
# 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
   133
# 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
   134
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
   135
    """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
   136
    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
   137
    """
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
   138
    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
   139
    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
   140
        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
   141
            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
   142
        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
   143
            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
   144
    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
   145
    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
   146
        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
   147
        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
   148
                        % 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
   149
    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
   150
    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
   151
        # 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
   152
        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
   153
            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
   154
                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
   155
                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
   156
                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
   157
                    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
   158
                        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
   159
                    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
   160
                        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
   161
    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
   162
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
def bw_normalize_etype(etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
    if etype in ETYPE_NAME_MAP:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
        msg = '%s has been renamed to %s, please update your code' % (
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   166
            etype, ETYPE_NAME_MAP[etype])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        warn(msg, DeprecationWarning, stacklevel=4)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        etype = ETYPE_NAME_MAP[etype]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
    return etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
3275
5247789df541 [gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3240
diff changeset
   171
def display_name(req, key, form='', context=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
    """return a internationalized string for the key (schema entity or relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
    name) in a given form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
    assert form in ('', 'plural', 'subject', 'object')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
    if form == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        form = ''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
    if form:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
        key = key + '_' + form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
    # ensure unicode
3284
036cf5a25714 ensure pgettext return unicode as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3275
diff changeset
   181
    if context is not None:
7951
b7c825b00f64 [schema display] display_name shouldn't call .lower(). Note the only proper way is to have different msgid for upper/lower cases. Closes #1105433
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7894
diff changeset
   182
        return unicode(req.pgettext(context, key))
3275
5247789df541 [gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3240
diff changeset
   183
    else:
7951
b7c825b00f64 [schema display] display_name shouldn't call .lower(). Note the only proper way is to have different msgid for upper/lower cases. Closes #1105433
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7894
diff changeset
   184
        return unicode(req._(key))
3275
5247789df541 [gettext] provide GNU contexts to avoid translations ambiguities
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3240
diff changeset
   185
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   186
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   187
# Schema objects definition ###################################################
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   188
3471
8c57c71b859c can now give context to rschema.display_name(...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3401
diff changeset
   189
def ERSchema_display_name(self, req, form='', context=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
    """return a internationalized string for the entity/relation type name in
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
    a given form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
    """
3471
8c57c71b859c can now give context to rschema.display_name(...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3401
diff changeset
   193
    return display_name(req, self.type, form, context)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
ERSchema.display_name = ERSchema_display_name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
@cached
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   197
def get_groups(self, action):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
    """return the groups authorized to perform <action> on entities of
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
    this type
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
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
    :rtype: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
    :return: names of the groups with the given permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
    #assert action in self._groups, '%s %s' % (self, action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
    try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   210
        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
   211
    except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
        return ()
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   213
PermissionMixIn.get_groups = get_groups
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
@cached
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   216
def get_rqlexprs(self, action):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
    """return the rql expressions representing queries to check the user is allowed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
    to perform <action> on entities of this type
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
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
    :rtype: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
    :return: the rql expressions with the given permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
    #assert action in self._rqlexprs, '%s %s' % (self, action)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
    try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   229
        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
   230
    except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        return ()
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   232
PermissionMixIn.get_rqlexprs = get_rqlexprs
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   234
orig_set_action_permissions = PermissionMixIn.set_action_permissions
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   235
def set_action_permissions(self, action, permissions):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
    """set the groups and rql expressions allowing to perform <action> on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
    entities of this type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
    :type action: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
    :param action: the name of a permission
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
    :type permissions: tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
    :param permissions: the groups and rql expressions allowing the given action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
    """
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   245
    orig_set_action_permissions(self, action, tuple(permissions))
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   246
    clear_cache(self, 'get_rqlexprs')
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   247
    clear_cache(self, 'get_groups')
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   248
PermissionMixIn.set_action_permissions = set_action_permissions
0
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
def has_local_role(self, action):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
    """return true if the action *may* be granted localy (eg either rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
    expressions or the owners group are used in security definition)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
    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
   255
    'add' action checking. Also find a better name would be nice.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
    assert action in self.ACTIONS, action
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
    if self.get_rqlexprs(action):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
    if action in ('update', 'delete'):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   261
        return 'owners' in self.get_groups(action)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
    return False
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   263
PermissionMixIn.has_local_role = has_local_role
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   264
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   265
def may_have_permission(self, action, req):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   266
    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
   267
                                 self.has_perm(req, 'read')):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   268
        return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   269
    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
   270
PermissionMixIn.may_have_permission = may_have_permission
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   271
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   272
def has_perm(self, _cw, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   273
    """return true if the action is granted globaly or localy"""
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   274
    try:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   275
        self.check_perm(_cw, action, **kwargs)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   276
        return True
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   277
    except Unauthorized:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   278
        return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   279
PermissionMixIn.has_perm = has_perm
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   280
9148
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   281
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   282
def check_perm(self, _cw, action, **kwargs):
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   283
    # NB: _cw may be a server transaction or a request object.
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   284
    #
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   285
    # check user is in an allowed group, if so that's enough internal
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   286
    # transactions should always stop there
9148
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   287
    DBG = False
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   288
    if server.DEBUG & server.DBG_SEC:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   289
        if action in server._SECURITY_CAPS:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   290
            _self_str = str(self)
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   291
            if server._SECURITY_ITEMS:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   292
                if any(item in _self_str for item in server._SECURITY_ITEMS):
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   293
                    DBG = True
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   294
            else:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   295
                DBG = True
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   296
    groups = self.get_groups(action)
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   297
    if _cw.user.matching_groups(groups):
9148
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   298
        if DBG:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   299
            print 'check_perm: %r %r: user matches %s' % (action, _self_str, groups)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   300
        return
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   301
    # 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
   302
    # object, if so that's enough
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   303
    #
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   304
    # NB: give _cw to user.owns since user is not be bound to a transaction on
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   305
    # the repository side
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
   306
    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
   307
          kwargs.get('creating')
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   308
          or ('eid' in kwargs and _cw.user.owns(kwargs['eid']))):
9148
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   309
        if DBG:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   310
            print ('check_perm: %r %r: user is owner or creation time' %
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   311
                   (action, _self_str))
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   312
        return
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   313
    # else if there is some rql expressions, check them
9148
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   314
    if DBG:
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   315
        print ('check_perm: %r %r %s' %
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   316
               (action, _self_str, [(rqlexpr, kwargs, rqlexpr.check(_cw, **kwargs))
1b549c1acd4f [schema,server] add a security debugging aid (closes #2920304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8945
diff changeset
   317
                                    for rqlexpr in self.get_rqlexprs(action)]))
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   318
    if any(rqlexpr.check(_cw, **kwargs)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   319
           for rqlexpr in self.get_rqlexprs(action)):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   320
        return
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   321
    raise Unauthorized(action, str(self))
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   322
PermissionMixIn.check_perm = check_perm
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   323
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   324
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   325
RelationDefinitionSchema._RPROPERTIES['eid'] = None
8945
ba9e3fbfa5a5 [schemaserial] serialize additional yams parameter for customs type
Vincent Michel <vincent.michel@logilab.fr>
parents: 8892
diff changeset
   326
# remember rproperties defined at this point. Others will have to be serialized in
ba9e3fbfa5a5 [schemaserial] serialize additional yams parameter for customs type
Vincent Michel <vincent.michel@logilab.fr>
parents: 8892
diff changeset
   327
# CWAttribute.extra_props
ba9e3fbfa5a5 [schemaserial] serialize additional yams parameter for customs type
Vincent Michel <vincent.michel@logilab.fr>
parents: 8892
diff changeset
   328
KNOWN_RPROPERTIES = RelationDefinitionSchema.ALL_PROPERTIES()
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   329
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   330
def rql_expression(self, expression, mainvars=None, eid=None):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   331
    """rql expression factory"""
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   332
    if self.rtype.final:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   333
        return ERQLExpression(expression, mainvars, eid)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   334
    return RRQLExpression(expression, mainvars, eid)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   335
RelationDefinitionSchema.rql_expression = rql_expression
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   336
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   337
orig_check_permission_definitions = RelationDefinitionSchema.check_permission_definitions
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   338
def check_permission_definitions(self):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   339
    orig_check_permission_definitions(self)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   340
    schema = self.subject.schema
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   341
    for action, groups in self.permissions.iteritems():
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   342
        for group_or_rqlexpr in groups:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   343
            if action == 'read' and \
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   344
                   isinstance(group_or_rqlexpr, RQLExpression):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   345
                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
   346
                raise BadSchemaDefinition(msg % self)
4574
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   347
            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
   348
                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
   349
                raise BadSchemaDefinition(msg % self)
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   350
            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
   351
                msg = "can't use ERQLExpression on %s, use a RRQLExpression"
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   352
                raise BadSchemaDefinition(msg % self)
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   353
RelationDefinitionSchema.check_permission_definitions = check_permission_definitions
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
class CubicWebEntitySchema(EntitySchema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
    """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
   358
    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
   359
    constraints on those relations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
    def __init__(self, schema=None, edef=None, eid=None, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
        super(CubicWebEntitySchema, self).__init__(schema, edef, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
        if eid is None and edef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   364
            eid = getattr(edef, 'eid', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
        self.eid = eid
4574
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   366
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   367
    def check_permission_definitions(self):
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   368
        super(CubicWebEntitySchema, self).check_permission_definitions()
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   369
        for groups in self.permissions.itervalues():
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   370
            for group_or_rqlexpr in groups:
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   371
                if isinstance(group_or_rqlexpr, RRQLExpression):
2380444d982c [schema] refactor/cleanup check_permissions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4570
diff changeset
   372
                    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
   373
                    raise BadSchemaDefinition(msg % self.type)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   374
6951
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   375
    def is_subobject(self, strict=False, skiprels=None):
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   376
        if skiprels is None:
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   377
            skiprels = SKIP_COMPOSITE_RELS
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   378
        else:
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   379
            skiprels += SKIP_COMPOSITE_RELS
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   380
        return super(CubicWebEntitySchema, self).is_subobject(strict,
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   381
                                                              skiprels=skiprels)
cb6314b09e0f [schema, ui] fix is_subobject to skip cw_source relation (else everything is considered as a subobject, since this relation is now composite)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6949
diff changeset
   382
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
    def attribute_definitions(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
        """return an iterator on attribute definitions
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   385
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
        attribute relations are a subset of subject relations where the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
        object's type is a final entity
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   388
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
        an attribute definition is a 2-uple :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
        * name of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
        * schema of the destination entity type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
        iter = super(CubicWebEntitySchema, self).attribute_definitions()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
        for rschema, attrschema in iter:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
            if rschema.type == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
            yield rschema, attrschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   398
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
   399
    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
   400
        """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
   401
        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
   402
        """
464edb198faa drop @ wildcard in relation subject/object, override main_attribute for proper behaviour
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2126
diff changeset
   403
        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
   404
            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
   405
                    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
   406
                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
   407
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
    def add_subject_relation(self, rschema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
        """register the relation schema as possible subject relation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
        super(CubicWebEntitySchema, self).add_subject_relation(rschema)
7467
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   411
        if rschema.final:
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   412
            if self.rdef(rschema).get('fulltextindexed'):
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   413
                self._update_has_text()
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   414
        elif rschema.fulltext_container:
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   415
            self._update_has_text()
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   416
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   417
    def add_object_relation(self, rschema):
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   418
        """register the relation schema as possible object relation"""
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   419
        super(CubicWebEntitySchema, self).add_object_relation(rschema)
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   420
        if rschema.fulltext_container:
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   421
            self._update_has_text()
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 del_subject_relation(self, rtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
        super(CubicWebEntitySchema, self).del_subject_relation(rtype)
7467
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   425
        if 'has_text' in self.subjrels:
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   426
            self._update_has_text(deletion=True)
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   427
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   428
    def del_object_relation(self, rtype):
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   429
        super(CubicWebEntitySchema, self).del_object_relation(rtype)
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   430
        if 'has_text' in self.subjrels:
5a6b3e51807d [schema] fix computing of has_text relation: when a fulltext_container relation is added, we need to recompute has_text for the target entity type as well. Also, avoid computation when not needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7152
diff changeset
   431
            self._update_has_text(deletion=True)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   432
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
   433
    def _update_has_text(self, deletion=False):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
        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
   435
        need_has_text = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
        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
   437
            if rschema.final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
                if rschema == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   439
                    has_has_text = True
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   440
                elif self.rdef(rschema).get('fulltextindexed'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   442
            elif rschema.fulltext_container:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
                if rschema.fulltext_container == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   445
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
                    need_has_text = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   447
        for rschema in self.object_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   448
            if rschema.fulltext_container:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
                if rschema.fulltext_container == 'object':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   450
                    may_need_has_text = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
                    need_has_text = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
        if need_has_text is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   454
            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
   455
        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
   456
            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
   457
                                          __permissions__=RO_ATTR_PERMS)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   458
            self.schema.add_relation_def(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
        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
   460
            # 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
   461
            # 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
   462
            self.schema['has_text'].del_relation_def(self, self.schema['String'])
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   463
5896
67683b7e591a cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
   464
    def schema_entity(self): # XXX @property for consistency with meta
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   465
        """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
   466
        return self.type in SCHEMA_TYPES
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
    def rql_expression(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
        """rql expression factory"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   470
        return ERQLExpression(expression, mainvars, eid)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   471
2252
dd9758cb77e1 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2222
diff changeset
   472
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
class CubicWebRelationSchema(RelationSchema):
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   474
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
    def __init__(self, schema=None, rdef=None, eid=None, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   476
        if rdef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
            # if this relation is inlined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
            self.inlined = rdef.inlined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
        super(CubicWebRelationSchema, self).__init__(schema, rdef, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
        if eid is None and rdef is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
            eid = getattr(rdef, 'eid', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
        self.eid = eid
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   483
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
   484
    @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
   485
    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
   486
        return self.type in META_RTYPES
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   487
5896
67683b7e591a cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
   488
    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
   489
        """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
   490
        return self.type in SCHEMA_TYPES
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   491
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   492
    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
   493
        if eschema is not None:
4019
7f68077d2c3b api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4005
diff changeset
   494
            for tschema in self.targets(eschema, role):
7f68077d2c3b api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4005
diff changeset
   495
                rdef = self.role_rdef(eschema, tschema, role)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   496
                if rdef.may_have_permission(action, req):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   497
                    return True
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   498
        else:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   499
            for rdef in self.rdefs.itervalues():
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   500
                if rdef.may_have_permission(action, req):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   501
                    return True
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   502
        return False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   503
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   504
    def has_perm(self, _cw, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   505
        """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
   506
        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
   507
            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
   508
            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
   509
            if 'eid' in kwargs:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   510
                subjtype = _cw.describe(kwargs['eid'])[0]
4575
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   511
            else:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   512
                subjtype = objtype = None
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   513
        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
   514
            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
   515
            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
   516
            if 'fromeid' in kwargs:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   517
                subjtype = _cw.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
   518
            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
   519
                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
   520
            else:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   521
                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
   522
            if 'toeid' in kwargs:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   523
                objtype = _cw.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
   524
            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
   525
                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
   526
            else:
4a7fe84f7803 [schema] fix RelationSchema.has_perm to properly works with attribute relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4574
diff changeset
   527
                objtype = None
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   528
        if objtype and subjtype:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   529
            return self.rdef(subjtype, objtype).has_perm(_cw, action, **kwargs)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   530
        elif subjtype:
4004
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   531
            for tschema in self.targets(subjtype, 'subject'):
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   532
                rdef = self.rdef(subjtype, tschema)
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   533
                if not rdef.has_perm(_cw, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   534
                    return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   535
        elif objtype:
4004
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   536
            for tschema in self.targets(objtype, 'object'):
c52619c738a5 api renaming update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4003
diff changeset
   537
                rdef = self.rdef(tschema, objtype)
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   538
                if not rdef.has_perm(_cw, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   539
                    return False
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   540
        else:
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   541
            for rdef in self.rdefs.itervalues():
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   542
                if not rdef.has_perm(_cw, action, **kwargs):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   543
                    return False
4233
94ffaecd8e8c ouch, has_perm was always returning False...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   544
        return True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   545
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   546
    @deprecated('use .rdef(subjtype, objtype).role_cardinality(role)')
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   547
    def cardinality(self, subjtype, objtype, target):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   548
        return self.rdef(subjtype, objtype).role_cardinality(target)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   549
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   550
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   551
class CubicWebSchema(Schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   552
    """set of entities and relations schema defining the possible data sets
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
    used in an application
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   554
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   555
    :type name: str
2476
1294a6bdf3bf application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2460
diff changeset
   556
    :ivar name: name of the schema, usually the instance identifier
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   557
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
    :type base: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   559
    :ivar base: path of the directory where the schema is defined
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   560
    """
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   561
    reading_from_database = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   562
    entity_class = CubicWebEntitySchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
    relation_class = CubicWebRelationSchema
2958
44e5446b649b no inference for the identity relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2926
diff changeset
   564
    no_specialization_inference = ('identity',)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   565
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
    def __init__(self, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
        self._eid_index = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
        super(CubicWebSchema, self).__init__(*args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   569
        ybo.register_base_types(self)
2300
c8151d004e06 meta has been drop
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   570
        rschema = self.add_relation_type(ybo.RelationType('eid'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
        rschema.final = True
2300
c8151d004e06 meta has been drop
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   572
        rschema = self.add_relation_type(ybo.RelationType('has_text'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   573
        rschema.final = True
2300
c8151d004e06 meta has been drop
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   574
        rschema = self.add_relation_type(ybo.RelationType('identity'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   575
        rschema.final = False
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   576
7440
539de926ec9d [test] fix failure introduced by 1719eab69551: the regexp should be fixed, not the error message
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7383
diff changeset
   577
    etype_name_re = r'[A-Z][A-Za-z0-9]*[a-z]+[A-Za-z0-9]*$'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   578
    def add_entity_type(self, edef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   579
        edef.name = edef.name.encode()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
        edef.name = bw_normalize_etype(edef.name)
7383
1719eab69551 [schema] fix imprecise error message
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7152
diff changeset
   581
        if not re.match(self.etype_name_re, edef.name):
6861
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   582
            raise BadSchemaDefinition(
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   583
                '%r is not a valid name for an entity type. It should start '
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   584
                'with an upper cased letter and be followed by at least a '
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   585
                'lower cased letter' % edef.name)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   586
        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
   587
        if not eschema.final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   588
            # automatically add the eid relation to non final entity types
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   589
            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
   590
                                          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
   591
                                          __permissions__=RO_ATTR_PERMS)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
            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
   593
            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
   594
                                          __permissions__=RO_REL_PERMS)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   595
            self.add_relation_def(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   596
        self._eid_index[eschema.eid] = eschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
        return eschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   598
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   599
    def add_relation_type(self, rdef):
6861
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   600
        if not rdef.name.islower():
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   601
            raise BadSchemaDefinition(
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   602
                '%r is not a valid name for a relation type. It should be '
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   603
                'lower cased' % rdef.name)
9d4e11d6e783 [schema] ease understanding of schema naming error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6827
diff changeset
   604
        rdef.name = rdef.name.encode()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   605
        rschema = super(CubicWebSchema, self).add_relation_type(rdef)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   606
        self._eid_index[rschema.eid] = rschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   607
        return rschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   608
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   609
    def add_relation_def(self, rdef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   610
        """build a part of a relation schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   611
        (i.e. add a relation between two specific entity's types)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   612
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   613
        :type subject: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   614
        :param subject: entity's type that is subject of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   615
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   616
        :type rtype: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   617
        :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
   618
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   619
        :type obj: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   620
        :param obj: entity's type that is object of the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   621
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   622
        :rtype: RelationSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   623
        :param: the newly created or just completed relation schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   624
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   625
        rdef.name = rdef.name.lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   626
        rdef.subject = bw_normalize_etype(rdef.subject)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   627
        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
   628
        rdefs = super(CubicWebSchema, self).add_relation_def(rdef)
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   629
        if rdefs:
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   630
            try:
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   631
                self._eid_index[rdef.eid] = rdefs
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   632
            except AttributeError:
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   633
                pass # not a serialized schema
4003
b9436fe77c9e fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3998
diff changeset
   634
        return rdefs
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   635
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   636
    def del_relation_type(self, rtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   637
        rschema = self.rschema(rtype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   638
        self._eid_index.pop(rschema.eid, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   639
        super(CubicWebSchema, self).del_relation_type(rtype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   640
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   641
    def del_relation_def(self, subjtype, rtype, objtype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   642
        for k, v in self._eid_index.items():
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   643
            if not isinstance(v, RelationDefinitionSchema):
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   644
                continue
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   645
            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
   646
                del self._eid_index[k]
2718
3a56b87bb5d6 [schema] break when found
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2716
diff changeset
   647
                break
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   648
        super(CubicWebSchema, self).del_relation_def(subjtype, rtype, objtype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   649
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   650
    def del_entity_type(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   651
        eschema = self.eschema(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   652
        self._eid_index.pop(eschema.eid, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   653
        # deal with has_text first, else its automatic deletion (see above)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   654
        # may trigger an error in ancestor's del_entity_type method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   655
        if 'has_text' in eschema.subject_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   656
            self.del_relation_def(etype, 'has_text', 'String')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   657
        super(CubicWebSchema, self).del_entity_type(etype)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   658
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   659
    def schema_by_eid(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   660
        return self._eid_index[eid]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   661
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   662
# Bases for manipulating RQL in schema #########################################
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   663
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   664
def guess_rrqlexpr_mainvars(expression):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   665
    defined = set(split_expression(expression))
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   666
    mainvars = set()
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   667
    if 'S' in defined:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   668
        mainvars.add('S')
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   669
    if 'O' in defined:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   670
        mainvars.add('O')
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   671
    if 'U' in defined:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   672
        mainvars.add('U')
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   673
    if not mainvars:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   674
        raise Exception('unable to guess selection variables')
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   675
    return 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
   676
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   677
def split_expression(rqlstring):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   678
    for expr in rqlstring.split(','):
7603
1302aa6ba4da [schema / rql] fix mainvars of RRQLExpression with parens
Florent Cayré <florent.cayre@gmail.com>
parents: 7467
diff changeset
   679
        for noparen1 in expr.split('('):
1302aa6ba4da [schema / rql] fix mainvars of RRQLExpression with parens
Florent Cayré <florent.cayre@gmail.com>
parents: 7467
diff changeset
   680
            for noparen2 in noparen1.split(')'):
1302aa6ba4da [schema / rql] fix mainvars of RRQLExpression with parens
Florent Cayré <florent.cayre@gmail.com>
parents: 7467
diff changeset
   681
                for word in noparen2.split():
1302aa6ba4da [schema / rql] fix mainvars of RRQLExpression with parens
Florent Cayré <florent.cayre@gmail.com>
parents: 7467
diff changeset
   682
                    yield word
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   683
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   684
def normalize_expression(rqlstring):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   685
    """normalize an rql expression to ease schema synchronization (avoid
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   686
    suppressing and reinserting an expression if only a space has been
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   687
    added/removed for instance)
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
   688
    """
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   689
    return u', '.join(' '.join(expr.split()) for expr in rqlstring.split(','))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   690
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   691
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   692
class RQLExpression(object):
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   693
    """Base class for RQL expression used in schema (constraints and
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   694
    permissions)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   695
    """
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   696
    # these are overridden by set_log_methods below
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   697
    # only defining here to prevent pylint from complaining
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   698
    info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7782
diff changeset
   699
    # to be defined in concrete classes
9280
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   700
    rqlst = None
9227
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   701
    predefined_variables = None
7103
9acffa1ecb2f cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7085
diff changeset
   702
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   703
    def __init__(self, expression, mainvars, eid):
8160
e53c003e3d37 [doc] Add a small docstring to RQLExpression constructor
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8027
diff changeset
   704
        """
9227
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   705
        :type mainvars: sequence of RQL variables' names. Can be provided as a
8160
e53c003e3d37 [doc] Add a small docstring to RQLExpression constructor
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8027
diff changeset
   706
                        comma separated string.
e53c003e3d37 [doc] Add a small docstring to RQLExpression constructor
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8027
diff changeset
   707
        :param mainvars: names of the variables being selected.
e53c003e3d37 [doc] Add a small docstring to RQLExpression constructor
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8027
diff changeset
   708
e53c003e3d37 [doc] Add a small docstring to RQLExpression constructor
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 8027
diff changeset
   709
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   710
        self.eid = eid # eid of the entity representing this rql expression
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   711
        assert mainvars, 'bad mainvars %s' % mainvars
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   712
        if isinstance(mainvars, basestring):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   713
            mainvars = set(splitstrip(mainvars))
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   714
        elif not isinstance(mainvars, set):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   715
            mainvars = set(mainvars)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   716
        self.mainvars = mainvars
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   717
        self.expression = normalize_expression(expression)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   718
        try:
9280
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   719
            self.full_rql = self.rqlst.as_string()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   720
        except RQLSyntaxError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   721
            raise RQLSyntaxError(expression)
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   722
        for mainvar in mainvars:
9227
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   723
            # if variable is predefined, an extra reference is inserted
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   724
            # automatically (`VAR eid %(v)s`)
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   725
            if mainvar in self.predefined_variables:
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   726
                min_refs = 3
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   727
            else:
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   728
                min_refs = 2
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   729
            if len(self.rqlst.defined_vars[mainvar].references()) < min_refs:
2142
098aa2075903 include_schema_files is useless
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   730
                _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
   731
                             'expression %s', mainvar, self)
3825
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3824
diff changeset
   732
        # 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
   733
        self.snippet_rqlst = parse(self.minimal_rql, print_errors=False).children[0]
9262
7fc54e02291f [security] fix dumb attribute error when inserting read security. Closes #3196891
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9227
diff changeset
   734
        # graph of links between variables, used by rql rewriter
7fc54e02291f [security] fix dumb attribute error when inserting read security. Closes #3196891
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9227
diff changeset
   735
        self.vargraph = vargraph(self.rqlst)
9366
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
   736
        # useful for some instrumentation, e.g. localperms permcheck command
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
   737
        self.package = ybo.PACKAGE
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   738
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   739
    def __str__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   740
        return self.full_rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   741
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   742
        return '%s(%s)' % (self.__class__.__name__, self.full_rql)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   743
8892
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   744
    def __lt__(self, other):
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   745
        if hasattr(other, 'expression'):
8892
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   746
            return self.expression < other.expression
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   747
        return True
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   748
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   749
    def __eq__(self, other):
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   750
        if hasattr(other, 'expression'):
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   751
            return self.expression == other.expression
80783605d270 [toward-py3k] rewrite __cmp__ (closes #2715115)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8695
diff changeset
   752
        return False
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   753
9168
0fb4b67bde58 [schema/security] add __hash__ to rql expression. Closes #3013535
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8945
diff changeset
   754
    def __hash__(self):
0fb4b67bde58 [schema/security] add __hash__ to rql expression. Closes #3013535
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8945
diff changeset
   755
        return hash(self.expression)
0fb4b67bde58 [schema/security] add __hash__ to rql expression. Closes #3013535
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8945
diff changeset
   756
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   757
    def __deepcopy__(self, memo):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   758
        return self.__class__(self.expression, self.mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   759
    def __getstate__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   760
        return (self.expression, self.mainvars)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   761
    def __setstate__(self, state):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   762
        self.__init__(*state)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   763
9280
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   764
    @cachedproperty
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   765
    def rqlst(self):
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   766
        select = parse(self.minimal_rql, print_errors=False).children[0]
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   767
        defined = set(split_expression(self.expression))
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   768
        for varname in self.predefined_variables:
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   769
            if varname in defined:
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   770
                select.add_eid_restriction(select.get_variable(varname), varname.lower(), 'Substitute')
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   771
        return select
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   772
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   773
    # permission rql expression specific stuff #################################
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   774
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   775
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   776
    def transform_has_permission(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   777
        found = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   778
        rqlst = self.rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   779
        for var in rqlst.defined_vars.itervalues():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   780
            for varref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   781
                rel = varref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   782
                if rel is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   783
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   784
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   785
                    prefix, action, suffix = rel.r_type.split('_')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   786
                except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   787
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   788
                if prefix != 'has' or suffix != 'permission' or \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   789
                       not action in ('add', 'delete', 'update', 'read'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   790
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   791
                if found is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   792
                    found = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   793
                    rqlst.save_state()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   794
                assert rel.children[0].name == 'U'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   795
                objvar = rel.children[1].children[0].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   796
                rqlst.remove_node(rel)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   797
                selected = [v.name for v in rqlst.get_selected_variables()]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   798
                if objvar.name not in selected:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   799
                    colindex = len(selected)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   800
                    rqlst.add_selected(objvar)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   801
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   802
                    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
   803
                found.append((action, colindex))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   804
                # 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
   805
                uvrefs = rqlst.defined_vars['U'].references()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   806
                if len(uvrefs) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   807
                    rqlst.remove_node(uvrefs[0].relation())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   808
        if found is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   809
            rql = rqlst.as_string()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   810
            if len(rqlst.selection) == 1 and isinstance(rqlst.where, nodes.Relation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   811
                # 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
   812
                keyarg = rqlst.selection[0].name.lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   813
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   814
                keyarg = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   815
            rqlst.recover()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   816
            return rql, found, keyarg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   817
        return rqlst.as_string(), None, None
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   818
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   819
    def _check(self, _cw, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   820
        """return True if the rql expression is matching the given relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   821
        between fromeid and toeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   822
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   823
        _cw may be a request or a server side transaction
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   824
        """
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
   825
        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
   826
        if not creating and self.eid is not None:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   827
            key = (self.eid, tuple(sorted(kwargs.iteritems())))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   828
            try:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   829
                return _cw.local_perm_cache[key]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   830
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   831
                pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   832
        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
   833
        # 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
   834
        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
   835
            return True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   836
        if keyarg is None:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   837
            kwargs.setdefault('u', _cw.user.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   838
            try:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   839
                rset = _cw.execute(rql, kwargs, build_descr=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   840
            except NotImplementedError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   841
                self.critical('cant check rql expression, unsupported rql %s', rql)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   842
                if self.eid is not None:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   843
                    _cw.local_perm_cache[key] = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   844
                return False
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8540
diff changeset
   845
            except TypeResolverException as ex:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   846
                # some expression may not be resolvable with current kwargs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   847
                # (type conflict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   848
                self.warning('%s: %s', rql, str(ex))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   849
                if self.eid is not None:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   850
                    _cw.local_perm_cache[key] = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   851
                return False
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8540
diff changeset
   852
            except Unauthorized as ex:
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
   853
                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
   854
                if self.eid is not None:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   855
                    _cw.local_perm_cache[key] = 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
   856
                return False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   857
        else:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   858
            rset = _cw.eid_rset(kwargs[keyarg])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   859
        # if no special has_*_permission relation in the rql expression, just
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   860
        # check the result set contains something
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   861
        if has_perm_defs is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   862
            if rset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   863
                if self.eid is not None:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   864
                    _cw.local_perm_cache[key] = True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   865
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   866
        elif rset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   867
            # check every special has_*_permission relation is satisfied
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   868
            get_eschema = _cw.vreg.schema.eschema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   869
            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
   870
                for eaction, col in has_perm_defs:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   871
                    for i in xrange(len(rset)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   872
                        eschema = get_eschema(rset.description[i][col])
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   873
                        eschema.check_perm(_cw, eaction, eid=rset[i][col])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   874
                if self.eid is not None:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   875
                    _cw.local_perm_cache[key] = True
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   876
                return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   877
            except Unauthorized:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   878
                pass
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   879
        if self.eid is not None:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   880
            _cw.local_perm_cache[key] = False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   881
        return False
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   882
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   883
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   884
    def minimal_rql(self):
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   885
        return 'Any %s WHERE %s' % (','.join(sorted(self.mainvars)),
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   886
                                    self.expression)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   887
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   888
# rql expressions for use in permission definition #############################
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   889
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   890
class ERQLExpression(RQLExpression):
9280
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   891
    predefined_variables = 'XU'
9227
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   892
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   893
    def __init__(self, expression, mainvars=None, eid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   894
        RQLExpression.__init__(self, expression, mainvars or 'X', eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   895
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   896
    def check(self, _cw, eid=None, creating=False, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   897
        if 'X' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   898
            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
   899
                if creating:
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   900
                    return self._check(_cw, creating=True, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   901
                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
   902
            assert creating == False
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   903
            return self._check(_cw, x=eid, **kwargs)
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   904
        return self._check(_cw, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   905
3961
d1cbf77db999 fix RQLUniqueConstraint behaviour by using a DISTINCT query and allowing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3827
diff changeset
   906
7973
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   907
def vargraph(rqlst):
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   908
    """ builds an adjacency graph of variables from the rql syntax tree, e.g:
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   909
    Any O,S WHERE T subworkflow_exit S, T subworkflow WF, O state_of WF
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   910
    => {'WF': ['O', 'T'], 'S': ['T'], 'T': ['WF', 'S'], 'O': ['WF']}
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   911
    """
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   912
    vargraph = {}
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   913
    for relation in rqlst.get_nodes(nodes.Relation):
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   914
        try:
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   915
            rhsvarname = relation.children[1].children[0].variable.name
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   916
            lhsvarname = relation.children[0].name
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   917
        except AttributeError:
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   918
            pass
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   919
        else:
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   920
            vargraph.setdefault(lhsvarname, []).append(rhsvarname)
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   921
            vargraph.setdefault(rhsvarname, []).append(lhsvarname)
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   922
            #vargraph[(lhsvarname, rhsvarname)] = relation.r_type
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   923
    return vargraph
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   924
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   925
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   926
class GeneratedConstraint(object):
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   927
    def __init__(self, rqlst, mainvars):
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   928
        self.snippet_rqlst = rqlst
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   929
        self.mainvars = mainvars
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   930
        self.vargraph = vargraph(rqlst)
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   931
64639bc94e25 [entity] restrict creation form field vocabulary using __linkto information (closes #1799997)
Florent Cayré <florent.cayre@gmail.com>
parents: 7951
diff changeset
   932
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   933
class RRQLExpression(RQLExpression):
9280
bae0caa8477a [schema] edit syntax tree instead of playing with strings for RQLExpressions
Julien Cristau <julien.cristau@logilab.fr>
parents: 9262
diff changeset
   934
    predefined_variables = 'SOU'
9227
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
   935
0
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)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   940
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   941
    def check(self, _cw, fromeid=None, toeid=None):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   942
        kwargs = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   943
        if 'S' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   944
            if fromeid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   945
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   946
            kwargs['s'] = fromeid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   947
        if 'O' in self.rqlst.defined_vars:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   948
            if toeid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   949
                return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   950
            kwargs['o'] = toeid
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
   951
        return self._check(_cw, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
   952
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   953
4570
ede247bbbf62 follow yams api change: attributes permissions are now defined for
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   954
# 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
   955
# 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
   956
# attribute.
4586
440e340c61fe DEFAULT_ATTRPERMS is now public
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4575
diff changeset
   957
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
   958
    'managers', ERQLExpression('U has_update_permission X'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   959
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   960
# additional cw specific constraints ###########################################
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   961
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   962
class BaseRQLConstraint(RRQLExpression, BaseConstraint):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   963
    """base class for rql constraints"""
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   964
    distinct_query = None
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   965
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   966
    def serialize(self):
9253
77e31ede9b04 [schema] drop very old bw compat (pre 3.5.10)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9246
diff changeset
   967
        # start with a semicolon for bw compat, see below
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   968
        return ';' + ','.join(sorted(self.mainvars)) + ';' + self.expression
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   969
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   970
    @classmethod
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   971
    def deserialize(cls, value):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   972
        _, mainvars, expression = value.split(';', 2)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   973
        return cls(expression, mainvars)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   974
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   975
    def check(self, entity, rtype, value):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   976
        """return true if the value satisfy the constraint, else false"""
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   977
        # implemented as a hook in the repository
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   978
        return 1
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   979
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   980
    def __str__(self):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   981
        if self.distinct_query:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   982
            selop = 'Any'
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   983
        else:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   984
            selop = 'DISTINCT Any'
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   985
        return '%s(%s %s WHERE %s)' % (self.__class__.__name__, selop,
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   986
                                       ','.join(sorted(self.mainvars)),
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   987
                                       self.expression)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   988
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   989
    def __repr__(self):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   990
        return '<%s @%#x>' % (self.__str__(), id(self))
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   991
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   992
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   993
class RQLVocabularyConstraint(BaseRQLConstraint):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   994
    """the rql vocabulary constraint:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   995
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   996
    limit the proposed values to a set of entities returned by a rql query,
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   997
    but this is not enforced at the repository level
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   998
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
   999
     `expression` is additional rql restriction that will be added to
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1000
     a predefined query, where the S and O variables respectivly represent
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1001
     the subject and the object of the relation
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1002
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1003
     `mainvars` is a set of variables that should be used as selection variable
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1004
     (eg `'Any %s WHERE ...' % mainvars`). If not specified, an attempt will be
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1005
     done to guess it according to variable used in the expression.
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1006
    """
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1007
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1008
    def repo_check(self, session, eidfrom, rtype, eidto):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1009
        """raise ValidationError if the relation doesn't satisfy the constraint
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1010
        """
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7973
diff changeset
  1011
        pass # this is a vocabulary constraint, not enforced
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1012
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1013
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1014
class RepoEnforcedRQLConstraintMixIn(object):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1015
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1016
    def __init__(self, expression, mainvars=None, msg=None):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1017
        super(RepoEnforcedRQLConstraintMixIn, self).__init__(expression, mainvars)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1018
        self.msg = msg
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1019
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1020
    def serialize(self):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1021
        # start with a semicolon for bw compat, see below
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1022
        return ';%s;%s\n%s' % (','.join(sorted(self.mainvars)), self.expression,
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1023
                               self.msg or '')
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1024
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1025
    def deserialize(cls, value):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1026
        value, msg = value.split('\n', 1)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1027
        _, mainvars, expression = value.split(';', 2)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1028
        return cls(expression, mainvars, msg)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1029
    deserialize = classmethod(deserialize)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1030
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1031
    def repo_check(self, session, eidfrom, rtype, eidto=None):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1032
        """raise ValidationError if the relation doesn't satisfy the constraint
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1033
        """
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1034
        if not self.match_condition(session, eidfrom, eidto):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1035
            # XXX at this point if both or neither of S and O are in mainvar we
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1036
            # dunno if the validation error `occurred` on eidfrom or eidto (from
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1037
            # user interface point of view)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1038
            #
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1039
            # possible enhancement: check entity being created, it's probably
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1040
            # the main eid unless this is a composite relation
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1041
            if eidto is None or 'S' in self.mainvars or not 'O' in self.mainvars:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1042
                maineid = eidfrom
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1043
                qname = role_name(rtype, 'subject')
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1044
            else:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1045
                maineid = eidto
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1046
                qname = role_name(rtype, 'object')
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1047
            if self.msg:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1048
                msg = session._(self.msg)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1049
            else:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1050
                msg = '%(constraint)s %(expression)s failed' % {
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1051
                    'constraint':  session._(self.type()),
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1052
                    'expression': self.expression}
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1053
            raise ValidationError(maineid, {qname: msg})
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1054
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
  1055
    def exec_query(self, _cw, eidfrom, eidto):
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1056
        if eidto is None:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1057
            # checking constraint for an attribute relation
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1058
            expression = 'S eid %(s)s, ' + self.expression
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1059
            args = {'s': eidfrom}
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1060
        else:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1061
            expression = 'S eid %(s)s, O eid %(o)s, ' + self.expression
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1062
            args = {'s': eidfrom, 'o': eidto}
7640
85ebdbbcb321 [schema] closes #1816439: RQLConstraint does not take variable U into account
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7603
diff changeset
  1063
        if 'U' in self.rqlst.defined_vars:
85ebdbbcb321 [schema] closes #1816439: RQLConstraint does not take variable U into account
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7603
diff changeset
  1064
            expression = 'U eid %(u)s, ' + expression
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
  1065
            args['u'] = _cw.user.eid
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1066
        rql = 'Any %s WHERE %s' % (','.join(sorted(self.mainvars)), expression)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1067
        if self.distinct_query:
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1068
            rql = 'DISTINCT ' + rql
8540
fee98af8bb33 [schema] rename schema permissions function: session may also be a request, use _cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8258
diff changeset
  1069
        return _cw.execute(rql, args, build_descr=False)
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1070
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1071
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1072
class RQLConstraint(RepoEnforcedRQLConstraintMixIn, RQLVocabularyConstraint):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1073
    """the rql constraint is similar to the RQLVocabularyConstraint but
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1074
    are also enforced at the repository level
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1075
    """
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1076
    distinct_query = False
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1077
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1078
    def match_condition(self, session, eidfrom, eidto):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1079
        return self.exec_query(session, eidfrom, eidto)
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1080
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1081
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1082
class RQLUniqueConstraint(RepoEnforcedRQLConstraintMixIn, BaseRQLConstraint):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1083
    """the unique rql constraint check that the result of the query isn't
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1084
    greater than one.
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1085
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1086
    You *must* specify `mainvars` when instantiating the constraint since there
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1087
    is no way to guess it correctly (e.g. if using S,O or U the constraint will
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1088
    always be satisfied because we've to use a DISTINCT query).
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1089
    """
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1090
    # XXX turns mainvars into a required argument in __init__
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1091
    distinct_query = True
9227
762a331db741 [schema] fix spurious warning when rqlexpr/constraint mainvars specify a non predefined variable. Closes #3098165
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9173
diff changeset
  1092
7152
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1093
    def match_condition(self, session, eidfrom, eidto):
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1094
        return len(self.exec_query(session, eidfrom, eidto)) <= 1
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1095
39c1ffc7d93f [schema, refactoring] use RQLExpression as base class for RQL constraint classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7103
diff changeset
  1096
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
  1097
# 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
  1098
2460
ce1a7ffc6c90 fix a couple NameErrors
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 2459
diff changeset
  1099
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
  1100
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
  1101
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
  1102
    """extends default EntityType's metaclass to add workflow relations
5378
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
  1103
    (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
  1104
    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
  1105
    """
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
  1106
    def __new__(mcs, name, bases, classdict):
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1107
        abstract = classdict.pop('__abstract__', False)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1108
        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
  1109
                                                          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
  1110
        if not abstract:
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1111
            make_workflowable(cls)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1112
        return cls
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1113
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
  1114
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
  1115
    """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
  1116
    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
  1117
    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
  1118
    """
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
  1119
    __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
  1120
    __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
  1121
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
  1122
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
  1123
def make_workflowable(cls, in_state_descr=None):
5378
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
  1124
    """Adds workflow relations as :class:`WorkflowableEntityType`, but usable on
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
  1125
    existing classes which are not using that base class.
0f54a0e128ac [schema] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5372
diff changeset
  1126
    """
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1127
    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
  1128
    # 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
  1129
    # 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
  1130
    etype = getattr(cls, 'name', cls.__name__)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1131
    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
  1132
        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
  1133
        yams_add_relation(cls.__relations__, rdef)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1134
    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
  1135
        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
  1136
                                      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
  1137
        yams_add_relation(cls.__relations__, rdef)
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2782
diff changeset
  1138
    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
  1139
        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
  1140
        yams_add_relation(cls.__relations__, rdef)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1141
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
  1142
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1143
# schema loading ##############################################################
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
CONSTRAINTS['RQLConstraint'] = RQLConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1146
CONSTRAINTS['RQLUniqueConstraint'] = RQLUniqueConstraint
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1147
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
  1148
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
  1149
PyFileReader.context.update(CONSTRAINTS)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1150
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1151
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1152
class BootstrapSchemaLoader(SchemaLoader):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1153
    """cubicweb specific schema loader, loading only schema necessary to read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1154
    the persistent schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1155
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1156
    schemacls = CubicWebSchema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1157
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
  1158
    def load(self, config, path=(), **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1159
        """return a Schema instance from the schema definition read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1160
        from <directory>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1161
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1162
        return super(BootstrapSchemaLoader, self).load(
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
  1163
            path, config.appid, register_base_types=False, **kwargs)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1164
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1165
    def _load_definition_files(self, cubes=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1166
        # bootstraping, ignore cubes
2735
39c942241b48 no need for lib_directory
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2730
diff changeset
  1167
        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
  1168
        self.info('loading %s', filepath)
9366
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
  1169
        with tempattr(ybo, 'PACKAGE', 'cubicweb'): # though we don't care here
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
  1170
            self.handle_file(filepath)
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1171
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1172
    def unhandled_file(self, filepath):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1173
        """called when a file without handler associated has been found"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1174
        self.warning('ignoring file %r', filepath)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1175
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6861
diff changeset
  1176
    # these are overridden by set_log_methods below
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6861
diff changeset
  1177
    # only defining here to prevent pylint from complaining
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6861
diff changeset
  1178
    info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1179
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1180
class CubicWebSchemaLoader(BootstrapSchemaLoader):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1181
    """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
  1182
    instance's schema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1183
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1184
1034
0356bbfb2f26 fix to pass arguments to base class
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
  1185
    def load(self, config, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1186
        """return a Schema instance from the schema definition read
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1187
        from <directory>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1188
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1189
        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
  1190
        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
  1191
        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
  1192
            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
  1193
                self.extrapath[cubesdir] = 'cubes'
372
a8a975a88368 check apphome is not None
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 0
diff changeset
  1194
        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
  1195
            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
  1196
        else:
2598
a66fe74bd9fc [R schema] dont give an iterator, it's a trap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2596
diff changeset
  1197
            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
  1198
        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
  1199
            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
  1200
        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
  1201
            # 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
  1202
            cleanup_sys_modules([join(cubicweb.CW_SOFTWARE_ROOT, 'schemas')])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1203
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1204
    def _load_definition_files(self, cubes):
2741
148d0cea1fb5 [schema] oops
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2736
diff changeset
  1205
        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
  1206
                         join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'base.py'),
148d0cea1fb5 [schema] oops
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2736
diff changeset
  1207
                         join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'workflow.py'),
148d0cea1fb5 [schema] oops
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2736
diff changeset
  1208
                         join(cubicweb.CW_SOFTWARE_ROOT, 'schemas', 'Bookmark.py')):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1209
            self.info('loading %s', filepath)
9366
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
  1210
            with tempattr(ybo, 'PACKAGE', 'cubicweb'):
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
  1211
                self.handle_file(filepath)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1212
        for cube in cubes:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1213
            for filepath in self.get_schema_files(cube):
9366
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
  1214
                with tempattr(ybo, 'PACKAGE', basename(cube)):
bcbc92223b35 set proper PACKAGE information for yams 0.39
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9283
diff changeset
  1215
                    self.handle_file(filepath)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1216
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6861
diff changeset
  1217
    # these are overridden by set_log_methods below
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6861
diff changeset
  1218
    # only defining here to prevent pylint from complaining
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6861
diff changeset
  1219
    info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1220
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
  1221
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
  1222
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
  1223
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
  1224
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1225
# _() 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
  1226
# translation
7797
a71618a75b53 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7782
diff changeset
  1227
MAY_USE_TEMPLATE_FORMAT = set(('managers',))
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
  1228
NEED_PERM_FORMATS = [_('text/cubicweb-page-template')]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1229
2531
531ea4e7013e [cleanup] nicer imports
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2526
diff changeset
  1230
@monkeypatch(FormatConstraint)
3347
428f95118556 fix vocab param to avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3287
diff changeset
  1231
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
  1232
    cw = None
3347
428f95118556 fix vocab param to avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3287
diff changeset
  1233
    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
  1234
        cw = entity._cw
3347
428f95118556 fix vocab param to avoid deprecation warning
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3287
diff changeset
  1235
    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
  1236
        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
  1237
    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
  1238
        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
  1239
            # 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
  1240
            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
  1241
                      not cw.is_hook_category_activated('integrity') or \
7797
a71618a75b53 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7782
diff changeset
  1242
                      cw.user.matching_groups(MAY_USE_TEMPLATE_FORMAT)
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
  1243
        else:
7797
a71618a75b53 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7782
diff changeset
  1244
            hasperm = cw.user.matching_groups(MAY_USE_TEMPLATE_FORMAT)
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
  1245
        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
  1246
            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
  1247
    return self.regular_formats
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1248
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1249
# XXX monkey patch PyFileReader.import_erschema until bw_normalize_etype is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1250
# necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1251
orig_import_erschema = PyFileReader.import_erschema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1252
def bw_import_erschema(self, ertype, schemamod=None, instantiate=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1253
    return orig_import_erschema(self, bw_normalize_etype(ertype), schemamod, instantiate)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1254
PyFileReader.import_erschema = bw_import_erschema
1451
982e8616d9a2 delete-trailing-whitespaces
sylvain.thenault@logilab.fr
parents: 1398
diff changeset
  1255
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1256
# XXX itou for some Statement methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1257
from rql import stmts
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1258
orig_get_etype = stmts.ScopeNode.get_etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1259
def bw_get_etype(self, name):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1260
    return orig_get_etype(self, bw_normalize_etype(name))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1261
stmts.ScopeNode.get_etype = bw_get_etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1262
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1263
orig_add_main_variable_delete = stmts.Delete.add_main_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1264
def bw_add_main_variable_delete(self, etype, vref):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1265
    return orig_add_main_variable_delete(self, bw_normalize_etype(etype), vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1266
stmts.Delete.add_main_variable = bw_add_main_variable_delete
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1267
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1268
orig_add_main_variable_insert = stmts.Insert.add_main_variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1269
def bw_add_main_variable_insert(self, etype, vref):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1270
    return orig_add_main_variable_insert(self, bw_normalize_etype(etype), vref)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1271
stmts.Insert.add_main_variable = bw_add_main_variable_insert
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1272
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1273
orig_set_statement_type = stmts.Select.set_statement_type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1274
def bw_set_statement_type(self, etype):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1275
    return orig_set_statement_type(self, bw_normalize_etype(etype))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1276
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
  1277
c5048502409f restore backward compat, still imported a lot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2735
diff changeset
  1278
# XXX deprecated
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1279
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
  1280
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
  1281
8125
7070250bf50d [schema] React to yams improvement of metadata attribute handling.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8027
diff changeset
  1282
RichString = moved('yams.buildobjs', '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
  1283
535705688f4f proper deprecation warning when import class that should be imported from yams
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4702
diff changeset
  1284
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
  1285
FormatConstraint = class_moved(FormatConstraint)
3978
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1286
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1287
PyFileReader.context['ERQLExpression'] = yobsolete(ERQLExpression)
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1288
PyFileReader.context['RRQLExpression'] = yobsolete(RRQLExpression)
2c95e3033f64 finish yesterday work on rql constraints:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3968
diff changeset
  1289
PyFileReader.context['WorkflowableEntityType'] = WorkflowableEntityType