3 :organization: Logilab |
3 :organization: Logilab |
4 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
4 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
7 """ |
7 """ |
|
8 from __future__ import with_statement |
|
9 |
8 __docformat__ = "restructuredtext en" |
10 __docformat__ = "restructuredtext en" |
9 |
11 |
10 from copy import copy |
12 from copy import copy |
11 |
13 |
12 from rql.stmts import Union, Select |
14 from rql.stmts import Union, Select |
13 from rql.nodes import Constant, Relation |
15 from rql.nodes import Constant, Relation |
14 |
16 |
15 from cubicweb import QueryError, typed_eid |
17 from cubicweb import QueryError, typed_eid |
16 from cubicweb.schema import VIRTUAL_RTYPES |
18 from cubicweb.schema import VIRTUAL_RTYPES |
17 from cubicweb.rqlrewrite import add_types_restriction |
19 from cubicweb.rqlrewrite import add_types_restriction |
|
20 from cubicweb.server.session import security_enabled |
18 |
21 |
19 READ_ONLY_RTYPES = set(('eid', 'has_text', 'is', 'is_instance_of', 'identity')) |
22 READ_ONLY_RTYPES = set(('eid', 'has_text', 'is', 'is_instance_of', 'identity')) |
20 |
23 |
21 _CONSTANT = object() |
24 _CONSTANT = object() |
22 _FROM_SUBSTEP = object() |
25 _FROM_SUBSTEP = object() |
56 def _extract_eid_consts(plan, rqlst): |
59 def _extract_eid_consts(plan, rqlst): |
57 """return a dict mapping rqlst variable object to their eid if specified in |
60 """return a dict mapping rqlst variable object to their eid if specified in |
58 the syntax tree |
61 the syntax tree |
59 """ |
62 """ |
60 session = plan.session |
63 session = plan.session |
61 eschema = session.vreg.schema.eschema |
|
62 if rqlst.where is None: |
64 if rqlst.where is None: |
63 return {} |
65 return {} |
64 eidconsts = {} |
66 eidconsts = {} |
65 neweids = session.transaction_data.get('neweids', ()) |
67 neweids = session.transaction_data.get('neweids', ()) |
66 checkread = session.read_security |
68 checkread = session.read_security |
|
69 eschema = session.vreg.schema.eschema |
67 for rel in rqlst.where.get_nodes(Relation): |
70 for rel in rqlst.where.get_nodes(Relation): |
68 if rel.r_type == 'eid' and not rel.neged(strict=True): |
71 if rel.r_type == 'eid' and not rel.neged(strict=True): |
69 lhs, rhs = rel.get_variable_parts() |
72 lhs, rhs = rel.get_variable_parts() |
70 if isinstance(rhs, Constant): |
73 if isinstance(rhs, Constant): |
71 eid = typed_eid(rhs.eval(plan.args)) |
74 eid = typed_eid(rhs.eval(plan.args)) |
72 # check read permission here since it may not be done by |
75 # check read permission here since it may not be done by |
73 # the generated select substep if not emited (eg nothing |
76 # the generated select substep if not emited (eg nothing |
74 # to be selected) |
77 # to be selected) |
75 if checkread and eid not in neweids: |
78 if checkread and eid not in neweids: |
76 eschema(session.describe(eid)[0]).check_perm(session, 'read') |
79 with security_enabled(session, read=False): |
|
80 eschema(session.describe(eid)[0]).check_perm( |
|
81 session, 'read', eid=eid) |
77 eidconsts[lhs.variable] = eid |
82 eidconsts[lhs.variable] = eid |
78 return eidconsts |
83 return eidconsts |
79 |
84 |
80 def _build_substep_query(select, origrqlst): |
85 def _build_substep_query(select, origrqlst): |
81 """Finalize substep select query that should be executed to get proper |
86 """Finalize substep select query that should be executed to get proper |