backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Sat, 18 Dec 2010 23:12:14 +0100
changeset 6751 02091c91520f
parent 6737 de49060d4be3 (current diff)
parent 6750 ef513c03a224 (diff)
child 6762 812445504835
backport stable
__pkginfo__.py
doc/book/en/annexes/cubicweb-ctl.rst
server/sources/ldapuser.py
--- a/__pkginfo__.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/__pkginfo__.py	Sat Dec 18 23:12:14 2010 +0100
@@ -52,7 +52,7 @@
     'Twisted': '',
     # XXX graphviz
     # server dependencies
-    'logilab-database': '>= 1.3.1',
+    'logilab-database': '>= 1.3.2',
     'pysqlite': '>= 2.5.5', # XXX install pysqlite2
     }
 
--- a/cwconfig.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/cwconfig.py	Sat Dec 18 23:12:14 2010 +0100
@@ -142,7 +142,7 @@
 from smtplib import SMTP
 from threading import Lock
 from os.path import (exists, join, expanduser, abspath, normpath,
-                     basename, isdir, dirname)
+                     basename, isdir, dirname, splitext)
 from warnings import warn
 from logilab.common.decorators import cached, classproperty
 from logilab.common.deprecation import deprecated
@@ -400,6 +400,13 @@
         return join(cls.shared_dir(), 'i18n')
 
     @classmethod
+    def cw_languages(cls):
+        for fname in os.listdir(join(cls.i18n_lib_dir())):
+            if fname.endswith('.po'):
+                yield splitext(fname)[0]
+
+
+    @classmethod
     def available_cubes(cls):
         import re
         cubes = set()
@@ -682,8 +689,8 @@
 
     def __init__(self, debugmode=False):
         register_stored_procedures()
-        ConfigurationMixIn.__init__(self)
         self._cubes = None
+        super(CubicWebNoAppConfiguration, self).__init__()
         self.debugmode = debugmode
         self.adjust_sys_path()
         self.load_defaults()
@@ -973,11 +980,15 @@
 
     def __init__(self, appid, debugmode=False):
         self.appid = appid
-        CubicWebNoAppConfiguration.__init__(self, debugmode)
+        super(CubicWebConfiguration, self).__init__(debugmode)
+        fake_gettext = (unicode, lambda ctx, msgid: unicode(msgid))
+        for lang in self.available_languages():
+            self.translations[lang] = fake_gettext
+        self._cubes = None
         self.load_file_configuration(self.main_config_file())
 
     def adjust_sys_path(self):
-        CubicWebNoAppConfiguration.adjust_sys_path(self)
+        super(CubicWebConfiguration, self).adjust_sys_path()
         # adding apphome to python path is not usually necessary in production
         # environments, but necessary for tests
         if self.apphome and not self.apphome in sys.path:
@@ -1075,8 +1086,8 @@
         if not force and hasattr(self, '_logging_initialized'):
             return
         self._logging_initialized = True
-        CubicWebNoAppConfiguration.init_log(self, logthreshold,
-                                            logfile=self.get('log-file'))
+        super_self = super(CubicWebConfiguration, self)
+        super_self.init_log(logthreshold, logfile=self.get('log-file'))
         # read a config file if it exists
         logconfig = join(self.apphome, 'logging.conf')
         if exists(logconfig):
--- a/cwvreg.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/cwvreg.py	Sat Dec 18 23:12:14 2010 +0100
@@ -462,7 +462,6 @@
     def clear(self): pass
     def initialization_completed(self): pass
 
-
 class CubicWebVRegistry(VRegistry):
     """Central registry for the cubicweb instance, extending the generic
     VRegistry with some cubicweb specific stuff.
@@ -560,14 +559,6 @@
         if self.is_reload_needed(path):
             self.reload(path)
 
-    def load_file(self, filepath, modname):
-        try:
-            super(CubicWebVRegistry, self).load_file(filepath, modname)
-        except ImportError:
-            if self.config.debugmode:
-                raise
-            self.exception('failed to load %s from %s', filepath, modname)
-
     def reload(self, path, force_reload=True):
         """modification detected, reset and reload the vreg"""
         CW_EVENT_MANAGER.emit('before-registry-reload')
--- a/debian/control	Thu Dec 09 15:27:02 2010 +0100
+++ b/debian/control	Sat Dec 18 23:12:14 2010 +0100
@@ -33,7 +33,7 @@
 Conflicts: cubicweb-multisources
 Replaces: cubicweb-multisources
 Provides: cubicweb-multisources
-Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-logilab-database (>= 1.3.1), cubicweb-postgresql-support | cubicweb-mysql-support | python-pysqlite2
+Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-logilab-database (>= 1.3.2), cubicweb-postgresql-support | cubicweb-mysql-support | python-pysqlite2
 Recommends: pyro (< 4.0.0), cubicweb-documentation (= ${source:Version})
 Description: server part of the CubicWeb framework
  CubicWeb is a semantic web application framework.
--- a/devtools/__init__.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/devtools/__init__.py	Sat Dec 18 23:12:14 2010 +0100
@@ -24,7 +24,7 @@
 import logging
 from datetime import timedelta
 from os.path import (abspath, join, exists, basename, dirname, normpath, split,
-                     isfile, isabs)
+                     isfile, isabs, splitext)
 
 from logilab.common.date import strptime
 from cubicweb import CW_SOFTWARE_ROOT, ConfigurationError, schema, cwconfig
@@ -181,7 +181,7 @@
     cube_appobject_path = TestServerConfiguration.cube_appobject_path | TwistedConfiguration.cube_appobject_path
 
     def available_languages(self, *args):
-        return ('en', 'fr', 'de')
+        return self.cw_languages()
 
     def pyro_enabled(self):
         # but export PYRO_MULTITHREAD=0 or you get problems with sqlite and
--- a/devtools/devctl.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/devtools/devctl.py	Sat Dec 18 23:12:14 2010 +0100
@@ -26,7 +26,7 @@
 # completion). So import locally in command helpers.
 import sys
 from datetime import datetime
-from os import mkdir, chdir, listdir, path as osp
+from os import mkdir, chdir, path as osp
 from warnings import warn
 
 from logilab.common import STD_BLACKLIST
@@ -34,6 +34,7 @@
 from cubicweb.__pkginfo__ import version as cubicwebversion
 from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage
 from cubicweb.cwctl import CWCTL
+from cubicweb.cwconfig import CubicWebNoAppConfiguration
 from cubicweb.toolsutils import (SKEL_EXCLUDE, Command, copy_skeleton,
                                  underline_title)
 from cubicweb.web.webconfig import WebConfiguration
@@ -64,6 +65,10 @@
     @property
     def apphome(self):
         return None
+
+    def available_languages(self):
+        return self.cw_languages()
+
     def main_config_file(self):
         return None
     def init_log(self):
@@ -264,11 +269,6 @@
 
 ''' % cubicwebversion
 
-def cw_languages():
-    for fname in listdir(osp.join(WebConfiguration.i18n_lib_dir())):
-        if fname.endswith('.po'):
-            yield osp.splitext(fname)[0]
-
 
 class UpdateCubicWebCatalogCommand(Command):
     """Update i18n catalogs for cubicweb library.
@@ -330,7 +330,7 @@
         print '-> merging main pot file with existing translations.'
         chdir(cwi18ndir)
         toedit = []
-        for lang in cw_languages():
+        for lang in CubicWebNoAppConfiguration.cw_languages():
             target = '%s.po' % lang
             execute('msgmerge -N --sort-output -o "%snew" "%s" "%s"'
                     % (target, target, cubicwebpot))
@@ -445,7 +445,7 @@
     print '-> merging main pot file with existing translations:'
     chdir('i18n')
     toedit = []
-    for lang in cw_languages():
+    for lang in CubicWebNoAppConfiguration.cw_languages():
         print '-> language', lang
         cubepo = '%s.po' % lang
         if not osp.exists(cubepo):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/admin/cubicweb-ctl.rst	Sat Dec 18 23:12:14 2010 +0100
@@ -0,0 +1,122 @@
+.. -*- coding: utf-8 -*-
+
+.. _cubicweb-ctl:
+
+``cubicweb-ctl`` tool
+=====================
+
+`cubicweb-ctl` is the swiss knife to manage *CubicWeb* instances.
+The general syntax is ::
+
+  cubicweb-ctl <command> [options command] <arguments commands>
+
+To view available commands ::
+
+  cubicweb-ctl
+  cubicweb-ctl --help
+
+Please note that the commands available depends on the *CubicWeb* packages
+and cubes that have been installed.
+
+To view the help menu on specific command ::
+
+  cubicweb-ctl <command> --help
+
+Listing available cubes and instance
+-------------------------------------
+
+* ``list``, provides a list of the available configuration, cubes
+  and instances.
+
+
+Creation of a new cube
+-----------------------
+
+Create your new cube cube ::
+
+   cubicweb-ctl newcube
+
+This will create a new cube in
+``/path/to/forest/cubicweb/cubes/<mycube>`` for a Mercurial forest
+installation, or in ``/usr/share/cubicweb/cubes`` for a debian
+packages installation.
+
+Create an instance
+-------------------
+
+You must ensure `~/cubicweb.d/` exists prior to this. On windows, the
+'~' part will probably expand to 'Documents and Settings/user'.
+
+To create an instance from an existing cube, execute the following
+command ::
+
+   cubicweb-ctl create <cube_name> <instance_name>
+
+This command will create the configuration files of an instance in
+``~/etc/cubicweb.d/<instance_name>``.
+
+The tool ``cubicweb-ctl`` executes the command ``db-create`` and
+``db-init`` when you run ``create`` so that you can complete an
+instance creation in a single command. But of course it is possible
+to issue these separate commands separately, at a later stage.
+
+Command to create/initialize an instance database
+-------------------------------------------------
+
+* ``db-create``, creates the system database of an instance (tables and
+  extensions only)
+* ``db-init``, initializes the system database of an instance
+  (schema, groups, users, workflows...)
+
+Commands to control instances
+-----------------------------
+
+* ``start``, starts one or more or all instances
+
+of special interest::
+
+  start -D
+
+will start in debug mode (under windows, starting without -D will not
+work; you need instead to setup your instance as a service).
+
+* ``stop``, stops one or more or all instances
+* ``restart``, restarts one or more or all instances
+* ``status``, returns the status of the instance(s)
+
+Commands to maintain instances
+------------------------------
+
+* ``upgrade``, launches the existing instances migration when a new version
+  of *CubicWeb* or the cubes installed is available
+* ``shell``, opens a (Python based) migration shell for manual maintenance of the instance
+* ``db-dump``, creates a dump of the system database
+* ``db-restore``, restores a dump of the system database
+* ``db-check``, checks data integrity of an instance. If the automatic correction
+  is activated, it is recommanded to create a dump before this operation.
+* ``schema-sync``, synchronizes the persistent schema of an instance with
+  the instance schema. It is recommanded to create a dump before this operation.
+
+Commands to maintain i18n catalogs
+----------------------------------
+* ``i18ncubicweb``, regenerates messages catalogs of the *CubicWeb* library
+* ``i18ncube``, regenerates the messages catalogs of a cube
+* ``i18ninstance``, recompiles the messages catalogs of an instance.
+  This is automatically done while upgrading.
+
+See also chapter :ref:`internationalization`.
+
+Other commands
+--------------
+* ``delete``, deletes an instance (configuration files and database)
+
+Command to create an instance for Google AppEngine datastore source
+-------------------------------------------------------------------
+* ``newgapp``, creates the configuration files for an instance
+
+This command needs to be followed by the commands responsible for
+the database initialization. As those are specific to the `datastore`,
+specific Google AppEgine database, they are not available for now
+in cubicweb-ctl, but they are available in the instance created.
+
+For more details, please see :ref:`GoogleAppEngineSource` .
--- a/doc/book/en/admin/index.rst	Thu Dec 09 15:27:02 2010 +0100
+++ b/doc/book/en/admin/index.rst	Sat Dec 18 23:12:14 2010 +0100
@@ -14,6 +14,7 @@
    :numbered:
 
    setup
+   cubicweb-ctl
    create-instance
    instance-config
    site-config
--- a/doc/book/en/annexes/cubicweb-ctl.rst	Thu Dec 09 15:27:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _cubicweb-ctl:
-
-``cubicweb-ctl`` tool
-=====================
-
-`cubicweb-ctl` is the swiss knife to manage *CubicWeb* instances.
-The general syntax is ::
-
-  cubicweb-ctl <command> [options command] <arguments commands>
-
-To view available commands ::
-
-  cubicweb-ctl
-  cubicweb-ctl --help
-
-Please note that the commands available depends on the *CubicWeb* packages
-and cubes that have been installed.
-
-To view the help menu on specific command ::
-
-  cubicweb-ctl <command> --help
-
-Listing available cubes and instance
--------------------------------------
-
-* ``list``, provides a list of the available configuration, cubes
-  and instances.
-
-
-Creation of a new cube
------------------------
-
-Create your new cube cube ::
-
-   cubicweb-ctl newcube
-
-This will create a new cube in
-``/path/to/forest/cubicweb/cubes/<mycube>`` for a Mercurial forest
-installation, or in ``/usr/share/cubicweb/cubes`` for a debian
-packages installation.
-
-Create an instance
--------------------
-
-You must ensure `~/cubicweb.d/` exists prior to this. On windows, the
-'~' part will probably expand to 'Documents and Settings/user'.
-
-To create an instance from an existing cube, execute the following
-command ::
-
-   cubicweb-ctl create <cube_name> <instance_name>
-
-This command will create the configuration files of an instance in
-``~/etc/cubicweb.d/<instance_name>``.
-
-The tool ``cubicweb-ctl`` executes the command ``db-create`` and
-``db-init`` when you run ``create`` so that you can complete an
-instance creation in a single command. But of course it is possible
-to issue these separate commands separately, at a later stage.
-
-Command to create/initialize an instance database
--------------------------------------------------
-
-* ``db-create``, creates the system database of an instance (tables and
-  extensions only)
-* ``db-init``, initializes the system database of an instance
-  (schema, groups, users, workflows...)
-
-Commands to control instances
------------------------------
-
-* ``start``, starts one or more or all instances
-
-of special interest::
-
-  start -D
-
-will start in debug mode (under windows, starting without -D will not
-work; you need instead to setup your instance as a service).
-
-* ``stop``, stops one or more or all instances
-* ``restart``, restarts one or more or all instances
-* ``status``, returns the status of the instance(s)
-
-Commands to maintain instances
-------------------------------
-
-* ``upgrade``, launches the existing instances migration when a new version
-  of *CubicWeb* or the cubes installed is available
-* ``shell``, opens a migration shell for manual maintenance of the instance
-* ``db-dump``, creates a dump of the system database
-* ``db-restore``, restores a dump of the system database
-* ``db-check``, checks data integrity of an instance. If the automatic correction
-  is activated, it is recommanded to create a dump before this operation.
-* ``schema-sync``, synchronizes the persistent schema of an instance with
-  the instance schema. It is recommanded to create a dump before this operation.
-
-Commands to maintain i18n catalogs
-----------------------------------
-* ``i18ncubicweb``, regenerates messages catalogs of the *CubicWeb* library
-* ``i18ncube``, regenerates the messages catalogs of a cube
-* ``i18ninstance``, recompiles the messages catalogs of an instance.
-  This is automatically done while upgrading.
-
-See also chapter :ref:`internationalization`.
-
-Other commands
---------------
-* ``delete``, deletes an instance (configuration files and database)
-
-Command to create an instance for Google AppEngine datastore source
--------------------------------------------------------------------
-* ``newgapp``, creates the configuration files for an instance
-
-This command needs to be followed by the commands responsible for
-the database initialization. As those are specific to the `datastore`,
-specific Google AppEgine database, they are not available for now
-in cubicweb-ctl, but they are available in the instance created.
-
-For more details, please see :ref:`GoogleAppEngineSource` .
--- a/doc/book/en/annexes/index.rst	Thu Dec 09 15:27:02 2010 +0100
+++ b/doc/book/en/annexes/index.rst	Sat Dec 18 23:12:14 2010 +0100
@@ -13,7 +13,6 @@
    :numbered:
 
    faq
-   cubicweb-ctl
    rql/index
    mercurial
    depends
--- a/doc/book/en/devrepo/testing.rst	Thu Dec 09 15:27:02 2010 +0100
+++ b/doc/book/en/devrepo/testing.rst	Sat Dec 18 23:12:14 2010 +0100
@@ -343,6 +343,60 @@
 therefore making new entity types and relations available to the
 tests. 
 
+Literate programming
+--------------------
+
+CubicWeb provides some literate programming capabilities. The :ref:`cubicweb-ctl`
+`shell` command accepts differents format files. If your file ends with `.txt`
+or `.rst`, the file will be parsed by :mod:`doctest.testfile` with CubicWeb
+:ref:`migration` API enabled in it.
+
+Create a `scenario.txt` file into `test/` directory and fill with some content.
+Please refer the :mod:`doctest.testfile` `documentation`_.
+
+.. _documentation: http://docs.python.org/library/doctest.html
+
+Then, you can run it directly by::
+
+    $ cubicweb-ctl shell <cube_instance> test/scenario.txt
+
+When your scenario file is ready, put it in a new test case to be able to run
+it automatically.
+
+.. sourcecode:: python
+
+      from os.path import dirname, join
+      from logilab.common.testlib import unittest_main
+      from cubicweb.devtools.testlib import CubicWebTC
+
+      class AcceptanceTC(CubicWebTC):
+
+              def test_scenario(self):
+                      self.assertDocTestFile(join(dirname(__file__), 'scenario.txt'))
+
+      if __name__ == '__main__':
+              unittest_main()
+
+Skipping a scenario
+```````````````````
+
+If you want to set up initial conditions that you can't put in your unit test
+case, you have to use a :exc:`KeyboardInterrupt` exception only because of the
+way :mod:`doctest` module will catch all the exceptions internally.
+
+    >>> if condition_not_met:
+    ...     raise KeyboardInterrupt('please, check your fixture.')
+
+Passing paramaters
+``````````````````
+Using extra arguments to parametrize your scenario is possible by prepend them
+by double dashes.
+
+Please refer to the `cubicweb-ctl shell --help` usage.
+
+.. important::
+    Your scenario file must be utf-8 encoded.
+
 Test APIS
 ---------
 
--- a/hooks/syncschema.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/hooks/syncschema.py	Sat Dec 18 23:12:14 2010 +0100
@@ -285,13 +285,15 @@
         self.session.vreg.schema.rename_entity_type(oldname, newname)
         # we need sql to operate physical changes on the system database
         sqlexec = self.session.system_sql
-        sqlexec('ALTER TABLE %s%s RENAME TO %s%s' % (SQL_PREFIX, oldname,
-                                                     SQL_PREFIX, newname))
+        dbhelper= self.session.pool.source('system').dbhelper
+        sql = dbhelper.sql_rename_table(SQL_PREFIX+oldname,
+                                        SQL_PREFIX+newname)
+        sqlexec(sql)
         self.info('renamed table %s to %s', oldname, newname)
-        sqlexec('UPDATE entities SET type=%s WHERE type=%s',
-                (newname, oldname))
-        sqlexec('UPDATE deleted_entities SET type=%s WHERE type=%s',
-                (newname, oldname))
+        sqlexec('UPDATE entities SET type=%(newname)s WHERE type=%(oldname)s',
+                {'newname': newname, 'oldname': oldname})
+        sqlexec('UPDATE deleted_entities SET type=%(newname)s WHERE type=%(oldname)s',
+                {'newname': newname, 'oldname': oldname})
         # XXX transaction records
 
     def precommit_event(self):
--- a/migration.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/migration.py	Sat Dec 18 23:12:14 2010 +0100
@@ -361,6 +361,9 @@
             import doctest
             return doctest.testfile(migrscript, module_relative=False,
                                     optionflags=doctest.ELLIPSIS,
+                                    # verbose mode when user input is expected
+                                    verbose=self.verbosity==2,
+                                    report=True,
                                     encoding='utf-8',
                                     globs=scriptlocals)
         self._context_stack.pop()
--- a/req.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/req.py	Sat Dec 18 23:12:14 2010 +0100
@@ -142,7 +142,7 @@
 
     def ensure_ro_rql(self, rql):
         """raise an exception if the given rql is not a select query"""
-        first = rql.split(' ', 1)[0].lower()
+        first = rql.split(None, 1)[0].lower()
         if first in ('insert', 'set', 'delete'):
             raise Unauthorized(self._('only select queries are authorized'))
 
--- a/server/hook.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/server/hook.py	Sat Dec 18 23:12:14 2010 +0100
@@ -747,7 +747,7 @@
                 MyOperation.get_instance(self._cw).add_data(self.entity)
 
 
-        class MyOperation(DataOperation, DataOperationMixIn):
+        class MyOperation(DataOperationMixIn, Operation):
             def precommit_event(self):
                 for bucket in self.get_data():
                     process(bucket)
--- a/server/schemaserial.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/server/schemaserial.py	Sat Dec 18 23:12:14 2010 +0100
@@ -126,8 +126,9 @@
                 sqlexec('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s'
                         % {'p': sqlutils.SQL_PREFIX}, {'x': eid, 'n': netype})
                 if etype.lower() != netype.lower():
-                    sqlexec('ALTER TABLE %s%s RENAME TO %s%s' % (
-                        sqlutils.SQL_PREFIX, etype, sqlutils.SQL_PREFIX, netype))
+                    alter_table_sql = dbhelper.sql_rename_table(sqlutils.SQL_PREFIX+etype,
+                                                                sqlutils.SQL_PREFIX+netype)
+                    sqlexec(alter_table_sql)
             sqlexec('UPDATE entities SET type=%(n)s WHERE type=%(x)s',
                     {'x': etype, 'n': netype})
             session.commit(False)
--- a/server/sources/ldapuser.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/server/sources/ldapuser.py	Sat Dec 18 23:12:14 2010 +0100
@@ -126,6 +126,12 @@
           'help': 'classes of user',
           'group': 'ldap-source', 'level': 1,
           }),
+        ('user-filter',
+         {'type': 'string',
+          'default': '',
+          'help': 'additional filters to be set in the ldap query to find valid users',
+          'group': 'ldap-source', 'level': 2,
+          }),
         ('user-login-attr',
          {'type' : 'string',
           'default': 'uid',
@@ -177,11 +183,11 @@
         self.user_login_attr = source_config['user-login-attr']
         self.user_default_groups = splitstrip(source_config['user-default-group'])
         self.user_attrs = dict(v.split(':', 1) for v in splitstrip(source_config['user-attrs-map']))
+        self.user_filter = source_config.get('user-filter')
         self.user_rev_attrs = {'eid': 'dn'}
         for ldapattr, cwattr in self.user_attrs.items():
             self.user_rev_attrs[cwattr] = ldapattr
-        self.base_filters = [filter_format('(%s=%s)', ('objectClass', o))
-                              for o in self.user_classes]
+        self.base_filters = self._make_base_filters()
         self._conn = None
         self._cache = {}
         # ttlm is in minutes!
@@ -194,6 +200,13 @@
                                     source_config.get('synchronization-interval',
                                                       24*60*60))
 
+    def _make_base_filters(self):
+        filters =  [filter_format('(%s=%s)', ('objectClass', o))
+                              for o in self.user_classes] 
+        if self.user_filter:
+            filters += [self.user_filter]
+        return filters
+
     def reset_caches(self):
         """method called during test to reset potential source caches"""
         self._cache = {}
@@ -287,8 +300,7 @@
             # we really really don't want that
             raise AuthenticationError()
         searchfilter = [filter_format('(%s=%s)', (self.user_login_attr, login))]
-        searchfilter.extend([filter_format('(%s=%s)', ('objectClass', o))
-                             for o in self.user_classes])
+        searchfilter.extend(self._make_base_filters())
         searchstr = '(&%s)' % ''.join(searchfilter)
         # first search the user
         try:
--- a/test/unittest_req.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/test/unittest_req.py	Sat Dec 18 23:12:14 2010 +0100
@@ -18,7 +18,7 @@
 from logilab.common.testlib import TestCase, unittest_main
 from cubicweb.req import RequestSessionBase
 from cubicweb.devtools.testlib import CubicWebTC
-
+from cubicweb import Unauthorized
 
 class RebuildURLTC(TestCase):
     def test_rebuild_url(self):
@@ -42,6 +42,12 @@
         self.assertRaises(AssertionError, req.build_url, 'one', 'two not allowed')
         self.assertRaises(AssertionError, req.build_url, 'view', test=None)
 
+    def test_ensure_no_rql(self):
+        req = RequestSessionBase(None)
+        self.assertEqual(req.ensure_ro_rql('Any X WHERE X is CWUser'), None)
+        self.assertEqual(req.ensure_ro_rql('  Any X WHERE X is CWUser  '), None)
+        self.assertRaises(Unauthorized, req.ensure_ro_rql, 'SET X login "toto" WHERE X is CWUser')
+        self.assertRaises(Unauthorized, req.ensure_ro_rql, '   SET X login "toto" WHERE X is CWUser   ')
 
 if __name__ == '__main__':
     unittest_main()
--- a/web/component.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/web/component.py	Sat Dec 18 23:12:14 2010 +0100
@@ -234,7 +234,7 @@
     # argument
     def render(self, w, **kwargs):
         if hasattr(self, 'call'):
-            warn('[3.10] should not anymore implements call on %s, see new CtxComponent api'
+            warn('[3.10] should not anymore implement call on %s, see new CtxComponent api'
                  % self.__class__, DeprecationWarning)
             self.w = w
             def wview(__vid, rset=None, __fallback_vid=None, **kwargs):
--- a/web/data/cubicweb.edition.js	Thu Dec 09 15:27:02 2010 +0100
+++ b/web/data/cubicweb.edition.js	Sat Dec 18 23:12:14 2010 +0100
@@ -11,7 +11,7 @@
 /**
  * .. function:: setPropValueWidget(varname, tabindex)
  *
- * called on Eproperty key selection:
+ * called on CWProperty key selection:
  * - get the selected value
  * - get a widget according to the key by a sync query to the server
  * - fill associated div with the returned html
@@ -65,12 +65,12 @@
                 vid: 'unrelateddivs',
                 relation: selectedValue,
                 rql: rql_for_eid(eid),
-                '__notemplate': 1,
-                callback: function() {
-                    _showMatchingSelect(eid, jQuery('#' + divId));
-                }
+                '__notemplate': 1
             };
-            jQuery('#unrelatedDivs_' + eid).loadxhtml(baseuri() + 'view', args, 'post', 'append');
+            var d = jQuery('#unrelatedDivs_' + eid).loadxhtml(baseuri() + 'view', args, 'post', 'append');
+            d.addCallback(function() {
+                _showMatchingSelect(eid, jQuery('#' + divId));
+            });
         } else {
             _showMatchingSelect(eid, divNode);
         }
@@ -209,7 +209,7 @@
         }
     }
     elementId = elementId.substring(2, elementId.length);
-    loadRemote('json', ajaxFuncArgs('remove_pending_inserts', null,
+    loadRemote('json', ajaxFuncArgs('remove_pending_insert', null,
                                     elementId.split(':')), 'GET', true);
 }
 
--- a/web/data/cubicweb.widgets.js	Thu Dec 09 15:27:02 2010 +0100
+++ b/web/data/cubicweb.widgets.js	Sat Dec 18 23:12:14 2010 +0100
@@ -91,6 +91,11 @@
                 };
                 var hiHandlers = methods.hiddenInputHandlers;
                 $(this).data('cwautocomplete', instanceData);
+                // in case of an existing value, the hidden input must be initialized even if
+                // the value is not changed
+                if (($(instanceData.userInput).attr('cubicweb:initialvalue') !== undefined) && !instanceData.hiddenInput){
+                    hiHandlers.initializeHiddenInput(instanceData);
+                }
                 $.ui.autocomplete.prototype._search = methods.search;
                 if (settings.multiple) {
                     $.ui.autocomplete.filter = methods.multiple.makeFilter(this);
--- a/web/views/autoform.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/web/views/autoform.py	Sat Dec 18 23:12:14 2010 +0100
@@ -550,6 +550,7 @@
         pending_inserts = set(get_pending_inserts(form._cw, form.edited_entity.eid))
         for pendingid in pending_inserts:
             eidfrom, rtype, eidto = pendingid.split(':')
+            pendingid = 'id' + pendingid
             if typed_eid(eidfrom) == entity.eid: # subject
                 label = display_name(form._cw, rtype, 'subject',
                                      entity.__regid__)
--- a/web/views/baseviews.py	Thu Dec 09 15:27:02 2010 +0100
+++ b/web/views/baseviews.py	Sat Dec 18 23:12:14 2010 +0100
@@ -188,7 +188,7 @@
     def cell_call(self, row, col):
         _ = self._cw._
         entity = self.cw_rset.get_entity(row, col)
-        self.w(u'<div class="metadata">')
+        self.w(u'<div>')
         if self.show_eid:
             self.w(u'%s #%s - ' % (entity.dc_type(), entity.eid))
         if entity.modification_date != entity.creation_date: