--- a/cwconfig.py Mon Jul 05 15:59:14 2010 +0200
+++ b/cwconfig.py Mon Jul 05 18:00:33 2010 +0200
@@ -131,6 +131,7 @@
Directory where pid files will be written
"""
+
__docformat__ = "restructuredtext en"
_ = unicode
@@ -985,12 +986,12 @@
@cached
def instance_md5_version(self):
- import md5
+ import hashlib
infos = []
for pkg in self.cubes():
version = self.cube_version(pkg)
infos.append('%s-%s' % (pkg, version))
- return md5.new(';'.join(infos)).hexdigest()
+ return hashlib.md5(';'.join(infos)).hexdigest()
def load_configuration(self):
"""load instance's configuration files"""
--- a/cwvreg.py Mon Jul 05 15:59:14 2010 +0200
+++ b/cwvreg.py Mon Jul 05 18:00:33 2010 +0200
@@ -189,6 +189,7 @@
.. automethod:: cubicweb.vregistry.Registry.object_by_id
"""
+
__docformat__ = "restructuredtext en"
_ = unicode
--- a/selectors.py Mon Jul 05 15:59:14 2010 +0200
+++ b/selectors.py Mon Jul 05 18:00:33 2010 +0200
@@ -191,6 +191,7 @@
.. |cubicweb| replace:: *CubicWeb*
"""
+
__docformat__ = "restructuredtext en"
import logging
--- a/server/querier.py Mon Jul 05 15:59:14 2010 +0200
+++ b/server/querier.py Mon Jul 05 18:00:33 2010 +0200
@@ -29,7 +29,8 @@
from logilab.common.compat import any
from rql import RQLSyntaxError
from rql.stmts import Union, Select
-from rql.nodes import Relation, VariableRef, Constant, SubQuery, Function
+from rql.nodes import (Relation, VariableRef, Constant, SubQuery, Function,
+ Exists, Not)
from cubicweb import Unauthorized, QueryError, UnknownEid, typed_eid
from cubicweb import server
@@ -113,7 +114,16 @@
ex = Unauthorized('read', solution[varname])
ex.var = varname
raise ex
- localchecks[varname] = erqlexprs
+ # don't insert security on variable only referenced by 'NOT X relation Y' or
+ # 'NOT EXISTS(X relation Y)'
+ varinfo = rqlst.defined_vars[varname].stinfo
+ if varinfo['selected'] or (
+ len([r for r in varinfo['relations']
+ if (not schema.rschema(r.r_type).final
+ and ((isinstance(r.parent, Exists) and r.parent.neged(strict=True))
+ or isinstance(r.parent, Not)))])
+ != len(varinfo['relations'])):
+ localchecks[varname] = erqlexprs
return localchecks
def add_noinvariant(noinvariant, restricted, select, nbtrees):
--- a/server/sources/rql2sql.py Mon Jul 05 15:59:14 2010 +0200
+++ b/server/sources/rql2sql.py Mon Jul 05 18:00:33 2010 +0200
@@ -428,16 +428,15 @@
p = compnode.parent
oor = None
while not isinstance(p, Select):
- if p in ors:
+ if p in ors or p is None: # p is None for nodes already in fakehaving
break
if isinstance(p, Or):
oor = p
p = p.parent
else:
node = oor or compnode
- if not node in fakehaving:
- fakehaving.append(node)
- compnode.parent.remove(node)
+ fakehaving.append(node)
+ node.parent.remove(node)
return fakehaving
class SQLGenerator(object):
--- a/server/test/unittest_hook.py Mon Jul 05 15:59:14 2010 +0200
+++ b/server/test/unittest_hook.py Mon Jul 05 18:00:33 2010 +0200
@@ -16,9 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""unit/functional tests for cubicweb.server.hook
-
-"""
+"""unit/functional tests for cubicweb.server.hook"""
from logilab.common.testlib import TestCase, unittest_main, mock_object
--- a/server/test/unittest_repository.py Mon Jul 05 15:59:14 2010 +0200
+++ b/server/test/unittest_repository.py Mon Jul 05 18:00:33 2010 +0200
@@ -212,7 +212,7 @@
def test_transaction_interleaved(self):
self.skip('implement me')
- def test_close_wait_processing_request(self):
+ def test_close_kill_processing_request(self):
repo = self.repo
cnxid = repo.connect(self.admlogin, password=self.admpassword)
repo.execute(cnxid, 'INSERT CWUser X: X login "toto", X upassword "tutu", X in_group G WHERE G name "users"')
@@ -223,9 +223,12 @@
repo.close(cnxid)
t = threading.Thread(target=close_in_a_few_moment)
t.start()
- try:
+ def run_transaction():
repo.execute(cnxid, 'DELETE CWUser X WHERE X login "toto"')
repo.commit(cnxid)
+ try:
+ ex = self.assertRaises(Exception, run_transaction)
+ self.assertEquals(str(ex), 'try to access pool on a closed session')
finally:
t.join()
--- a/server/test/unittest_rql2sql.py Mon Jul 05 15:59:14 2010 +0200
+++ b/server/test/unittest_rql2sql.py Mon Jul 05 18:00:33 2010 +0200
@@ -178,9 +178,8 @@
FROM cw_Personne AS _X
WHERE _X.cw_prenom=lulu AND NOT (EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, in_group_relation AS rel_in_group1, cw_CWGroup AS _G WHERE rel_owned_by0.eid_from=_X.cw_eid AND rel_in_group1.eid_from=rel_owned_by0.eid_to AND rel_in_group1.eid_to=_G.cw_eid AND ((_G.cw_name=lulufanclub) OR (_G.cw_name=managers))))'''),
-
+]
-]
ADVANCED= [
("Societe S WHERE S nom 'Logilab' OR S nom 'Caesium'",
@@ -575,6 +574,7 @@
]
+
MULTIPLE_SEL = [
("DISTINCT Any X,Y where P is Personne, P nom X , P prenom Y;",
'''SELECT DISTINCT _P.cw_nom, _P.cw_prenom
@@ -589,7 +589,9 @@
WHERE _Y.cw_nom=_X.cw_nom AND NOT (_Y.cw_eid=_X.cw_eid)''')
]
+
NEGATIONS = [
+
("Personne X WHERE NOT X evaluee Y;",
'''SELECT _X.cw_eid
FROM cw_Personne AS _X
@@ -1455,6 +1457,12 @@
'''SELECT (A || _X.cw_ref)
FROM cw_Affaire AS _X''')
+ def test_or_having_fake_terms(self):
+ self._check('Any X WHERE X is CWUser, X creation_date D HAVING YEAR(D) = "2010" OR D = NULL',
+ '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE ((CAST(EXTRACT(YEAR from _X.cw_creation_date) AS INTEGER)=2010) OR (_X.cw_creation_date IS NULL))''')
+
class SqliteSQLGeneratorTC(PostgresSQLGeneratorTC):
backend = 'sqlite'
@@ -1579,6 +1587,13 @@
yield t
+ def test_or_having_fake_terms(self):
+ self._check('Any X WHERE X is CWUser, X creation_date D HAVING YEAR(D) = "2010" OR D = NULL',
+ '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE ((YEAR(_X.cw_creation_date)=2010) OR (_X.cw_creation_date IS NULL))''')
+
+
class MySQLGenerator(PostgresSQLGeneratorTC):
backend = 'mysql'
@@ -1660,6 +1675,14 @@
'''SELECT SUBSTRING(_P.cw_nom, 1, 1)
FROM cw_Personne AS _P''')
+
+ def test_or_having_fake_terms(self):
+ self._check('Any X WHERE X is CWUser, X creation_date D HAVING YEAR(D) = "2010" OR D = NULL',
+ '''SELECT _X.cw_eid
+FROM cw_CWUser AS _X
+WHERE ((EXTRACT(YEAR from _X.cw_creation_date)=2010) OR (_X.cw_creation_date IS NULL))''')
+
+
class removeUnsusedSolutionsTC(TestCase):
def test_invariant_not_varying(self):
rqlst = mock_object(defined_vars={})
--- a/server/test/unittest_security.py Mon Jul 05 15:59:14 2010 +0200
+++ b/server/test/unittest_security.py Mon Jul 05 18:00:33 2010 +0200
@@ -15,8 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""functional tests for server'security
-"""
+"""functional tests for server'security"""
+
import sys
from logilab.common.testlib import unittest_main, TestCase
@@ -66,6 +66,27 @@
cu.execute, 'Any X,P WHERE X is CWUser, X upassword P')
+class SecurityRewritingTC(BaseSecurityTC):
+ def hijack_source_execute(self):
+ def syntax_tree_search(*args, **kwargs):
+ self.query = (args, kwargs)
+ return []
+ self.repo.system_source.syntax_tree_search = syntax_tree_search
+
+ def tearDown(self):
+ self.repo.system_source.__dict__.pop('syntax_tree_search', None)
+ BaseSecurityTC.tearDown(self)
+
+ def test_not_relation_read_security(self):
+ cnx = self.login('iaminusersgrouponly')
+ self.hijack_source_execute()
+ self.execute('Any U WHERE NOT A todo_by U, A is Affaire')
+ self.assertEquals(self.query[0][1].as_string(),
+ 'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire')
+ self.execute('Any U WHERE NOT EXISTS(A todo_by U), A is Affaire')
+ self.assertEquals(self.query[0][1].as_string(),
+ 'Any U WHERE NOT EXISTS(A todo_by U), A is Affaire')
+
class SecurityTC(BaseSecurityTC):
def setUp(self):
@@ -420,7 +441,6 @@
self.failUnless(x.creation_date)
cnx.rollback()
-
class BaseSchemaSecurityTC(BaseSecurityTC):
"""tests related to the base schema permission configuration"""
--- a/web/controller.py Mon Jul 05 15:59:14 2010 +0200
+++ b/web/controller.py Mon Jul 05 18:00:33 2010 +0200
@@ -15,10 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""abstract controller classe for CubicWeb web client
+"""abstract controller classe for CubicWeb web client"""
-
-"""
__docformat__ = "restructuredtext en"
from logilab.mtconverter import xml_escape
--- a/web/request.py Mon Jul 05 15:59:14 2010 +0200
+++ b/web/request.py Mon Jul 05 18:00:33 2010 +0200
@@ -20,12 +20,7 @@
__docformat__ = "restructuredtext en"
import Cookie
-try:
- import hashlib
- hashlib.hash
-except AttributeError:
- # python 2.5 ...
- import sha as hashlib
+import hashlib
import time
import random
import base64
@@ -369,9 +364,9 @@
def register_onetime_callback(self, func, *args):
cbname = 'cb_%s' % (
- hashlib.sha('%s%s%s%s' % (time.time(), func.__name__,
- random.random(),
- self.user.login)).hexdigest())
+ hashlib.sha1('%s%s%s%s' % (time.time(), func.__name__,
+ random.random(),
+ self.user.login)).hexdigest())
def _cb(req):
try:
ret = func(req, *args)
--- a/web/test/unittest_viewselector.py Mon Jul 05 15:59:14 2010 +0200
+++ b/web/test/unittest_viewselector.py Mon Jul 05 18:00:33 2010 +0200
@@ -16,8 +16,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""XXX rename, split, reorganize this
-"""
+"""XXX rename, split, reorganize this"""
+
from logilab.common.testlib import unittest_main
from cubicweb.devtools.testlib import CubicWebTC
--- a/web/views/embedding.py Mon Jul 05 15:59:14 2010 +0200
+++ b/web/views/embedding.py Mon Jul 05 18:00:33 2010 +0200
@@ -16,7 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Objects interacting together to provides the external page embeding
-functionality."""
+functionality.
+"""
__docformat__ = "restructuredtext en"