4 :organization: Logilab |
4 :organization: Logilab |
5 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
5 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
7 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
7 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
8 """ |
8 """ |
|
9 from __future__ import with_statement |
|
10 |
9 __docformat__ = "restructuredtext en" |
11 __docformat__ = "restructuredtext en" |
10 |
12 |
11 from itertools import repeat |
13 from itertools import repeat |
12 |
14 |
13 from logilab.common.cache import Cache |
15 from logilab.common.cache import Cache |
21 from cubicweb.rset import ResultSet |
23 from cubicweb.rset import ResultSet |
22 |
24 |
23 from cubicweb.server.utils import cleanup_solutions |
25 from cubicweb.server.utils import cleanup_solutions |
24 from cubicweb.server.rqlannotation import SQLGenAnnotator, set_qdata |
26 from cubicweb.server.rqlannotation import SQLGenAnnotator, set_qdata |
25 from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction |
27 from cubicweb.server.ssplanner import READ_ONLY_RTYPES, add_types_restriction |
26 |
28 from cubicweb.server.session import security_enabled |
27 |
29 |
28 def empty_rset(rql, args, rqlst=None): |
30 def empty_rset(rql, args, rqlst=None): |
29 """build an empty result set object""" |
31 """build an empty result set object""" |
30 return ResultSet([], rql, args, rqlst=rqlst) |
32 return ResultSet([], rql, args, rqlst=rqlst) |
31 |
33 |
198 """insert security when necessary then annotate rql st for sql generation |
200 """insert security when necessary then annotate rql st for sql generation |
199 |
201 |
200 return rqlst to actually execute |
202 return rqlst to actually execute |
201 """ |
203 """ |
202 noinvariant = set() |
204 noinvariant = set() |
203 if security and not self.session.is_super_session: |
205 if security and self.session.read_security: |
204 self._insert_security(union, noinvariant) |
206 # ensure security is turned of when security is inserted, |
|
207 # else we may loop for ever... |
|
208 with security_enabled(self.session, read=False): |
|
209 self._insert_security(union, noinvariant) |
205 self.rqlhelper.simplify(union) |
210 self.rqlhelper.simplify(union) |
206 self.sqlannotate(union) |
211 self.sqlannotate(union) |
207 set_qdata(self.schema.rschema, union, noinvariant) |
212 set_qdata(self.schema.rschema, union, noinvariant) |
208 if union.has_text_query: |
213 if union.has_text_query: |
209 self.cache_key = None |
214 self.cache_key = None |
297 So solutions which don't require local checks will be associated to |
302 So solutions which don't require local checks will be associated to |
298 the empty tuple key. |
303 the empty tuple key. |
299 |
304 |
300 note: rqlst should not have been simplified at this point |
305 note: rqlst should not have been simplified at this point |
301 """ |
306 """ |
302 assert not self.session.is_super_session |
|
303 user = self.session.user |
307 user = self.session.user |
304 schema = self.schema |
308 schema = self.schema |
305 msgs = [] |
309 msgs = [] |
306 # dictionnary of variables restricted for security reason |
310 # dictionnary of variables restricted for security reason |
307 localchecks = {} |
311 localchecks = {} |
599 # return an empty result instead of raising UnknownEid |
603 # return an empty result instead of raising UnknownEid |
600 return empty_rset(rql, args, rqlst) |
604 return empty_rset(rql, args, rqlst) |
601 self._rql_cache[cachekey] = rqlst |
605 self._rql_cache[cachekey] = rqlst |
602 orig_rqlst = rqlst |
606 orig_rqlst = rqlst |
603 if not rqlst.TYPE == 'select': |
607 if not rqlst.TYPE == 'select': |
604 if not session.is_super_session: |
608 if session.read_security: |
605 check_no_password_selected(rqlst) |
609 check_no_password_selected(rqlst) |
606 # write query, ensure session's mode is 'write' so connections |
610 # write query, ensure session's mode is 'write' so connections |
607 # won't be released until commit/rollback |
611 # won't be released until commit/rollback |
608 session.mode = 'write' |
612 session.mode = 'write' |
609 cachekey = None |
613 cachekey = None |
610 else: |
614 else: |
611 if not session.is_super_session: |
615 if session.read_security: |
612 for select in rqlst.children: |
616 for select in rqlst.children: |
613 check_no_password_selected(select) |
617 check_no_password_selected(select) |
614 # on select query, always copy the cached rqlst so we don't have to |
618 # on select query, always copy the cached rqlst so we don't have to |
615 # bother modifying it. This is not necessary on write queries since |
619 # bother modifying it. This is not necessary on write queries since |
616 # a new syntax tree is built from them. |
620 # a new syntax tree is built from them. |