diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index 5e4d1879ee3..2a7d7bb7f66 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -492,15 +492,19 @@ class res_config_settings(osv.osv_memory, res_config_module_installation_mixin): return res def execute(self, cr, uid, ids, context=None): + if uid != SUPERUSER_ID and not self.pool['res.users'].has_group(cr, uid, 'base.group_erp_manager'): + raise openerp.exceptions.AccessError(_("Only administrators can change the settings")) + ir_values = self.pool['ir.values'] ir_module = self.pool['ir.module.module'] + classified = self._get_classified_fields(cr, uid, context) config = self.browse(cr, uid, ids[0], context) # default values fields for name, model, field in classified['default']: - ir_values.set_default(cr, uid, model, field, config[name]) + ir_values.set_default(cr, SUPERUSER_ID, model, field, config[name]) # group fields: modify group / implied groups for name, group, implied_group in classified['group']: diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index 1acb55513c2..6d4b13c17ae 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -763,7 +763,6 @@ class users_view(osv.osv): def create(self, cr, uid, values, context=None): self._set_reified_groups(values) - return super(users_view, self).create(cr, uid, values, context) def write(self, cr, uid, ids, values, context=None): @@ -812,7 +811,7 @@ class users_view(osv.osv): if len(group_split) != 2: raise osv.except_osv(_('Invalid context value'), _('Invalid context default_groups_ref value (model.name_id) : "%s"') % group_xml_id) try: - temp, group_id = ir_model_data.get_object_reference(cr, uid, group_split[0], group_split[1]) + temp, group_id = ir_model_data.get_object_reference(cr, uid, group_split[0], group_split[1]) except ValueError: group_id = False groups += [group_id] @@ -820,14 +819,19 @@ class users_view(osv.osv): return values def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'): - if not fields: - fields = self.fields_get(cr, uid, context=context).keys() - group_fields, fields = partition(is_reified_group, fields) - if not 'groups_id' in fields: + fields_get = fields if fields is not None else self.fields_get(cr, uid, context=context).keys() + group_fields, _ = partition(is_reified_group, fields_get) + + inject_groups_id = group_fields and fields and 'groups_id' not in fields + if inject_groups_id: fields.append('groups_id') res = super(users_view, self).read(cr, uid, ids, fields, context=context, load=load) - for values in (res if isinstance(res, list) else [res]): - self._get_reified_groups(group_fields, values) + + if group_fields: + for values in (res if isinstance(res, list) else [res]): + self._get_reified_groups(group_fields, values) + if inject_groups_id: + values.pop('groups_id', None) return res def _get_reified_groups(self, fields, values): diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index e9a6da4c397..9a5533f5caa 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -342,7 +342,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): if processed_modules: cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""") for (model, name) in cr.fetchall(): - if model in registry and not registry[model].is_transient() and isinstance(registry[model], openerp.osv.orm.AbstractModel): + if model in registry and not registry[model].is_transient() and not isinstance(registry[model], openerp.osv.orm.AbstractModel): _logger.warning('The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,,1,1,1,1', model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_')) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index d0504300431..71053a02cae 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -383,10 +383,12 @@ class browse_record(object): self.__logger.debug(''.join(traceback.format_stack())) raise KeyError(error_msg) + prefetchable = lambda f: f._classic_write and f._prefetch and not f.groups and not f.deprecated + # if the field is a classic one or a many2one, we'll fetch all classic and many2one fields - if col._prefetch and not col.groups: + if prefetchable(col): # gen the list of "local" (ie not inherited) fields which are classic or many2one - field_filter = lambda x: x[1]._classic_write and x[1]._prefetch and not x[1].groups + field_filter = lambda x: prefetchable(x[1]) fields_to_fetch = filter(field_filter, self._table._columns.items()) # gen the list of inherited fields inherits = map(lambda x: (x[0], x[1][2]), self._table._inherit_fields.items()) @@ -4991,8 +4993,8 @@ class BaseModel(object): context = {} # avoid recursion through already copied records in case of circular relationship - seen_map = context.setdefault('__copy_data_seen',{}) - if id in seen_map.setdefault(self._name,[]): + seen_map = context.setdefault('__copy_data_seen', {}) + if id in seen_map.setdefault(self._name, []): return seen_map[self._name].append(id) @@ -5005,12 +5007,6 @@ class BaseModel(object): else: default['state'] = self._defaults['state'] - data = self.read(cr, uid, [id,], context=context) - if data: - data = data[0] - else: - raise IndexError( _("Record #%d of %s not found, cannot copy!") %( id, self._name)) - # build a black list of fields that should not be copied blacklist = set(MAGIC_COLUMNS + ['parent_left', 'parent_right']) def blacklist_given_fields(obj): @@ -5023,8 +5019,21 @@ class BaseModel(object): blacklist.update(set(self.pool[other]._all_columns) - set(self._columns)) else: blacklist_given_fields(self.pool[other]) + # blacklist deprecated fields + for name, field in obj._columns.items(): + if field.deprecated: + blacklist.add(name) + blacklist_given_fields(self) + fields_to_read = [f for f in self.check_field_access_rights(cr, uid, 'read', None) + if f not in blacklist] + data = self.read(cr, uid, [id], fields_to_read, context=context) + if data: + data = data[0] + else: + raise IndexError(_("Record #%d of %s not found, cannot copy!") % (id, self._name)) + res = dict(default) for f, colinfo in self._all_columns.items(): field = colinfo.column diff --git a/openerp/tests/addons/test_workflow/__openerp__.py b/openerp/tests/addons/test_workflow/__openerp__.py index 1b846f9f227..12cafa274e8 100644 --- a/openerp/tests/addons/test_workflow/__openerp__.py +++ b/openerp/tests/addons/test_workflow/__openerp__.py @@ -8,7 +8,7 @@ 'maintainer': 'OpenERP SA', 'website': 'http://www.openerp.com', 'depends': ['base'], - 'data': ['data.xml'], + 'data': ['data.xml', 'ir.model.access.csv'], 'installable': True, 'auto_install': False, } diff --git a/openerp/tests/addons/test_workflow/ir.model.access.csv b/openerp/tests/addons/test_workflow/ir.model.access.csv new file mode 100644 index 00000000000..6fb5a7ae274 --- /dev/null +++ b/openerp/tests/addons/test_workflow/ir.model.access.csv @@ -0,0 +1,15 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_test_workflow_model,access_test_workflow_model,model_test_workflow_model,,1,1,1,1 +access_test_workflow_trigger,access_test_workflow_trigger,model_test_workflow_trigger,,1,1,1,1 +access_test_workflow_model_a,access_test_workflow_model_a,model_test_workflow_model_a,,1,1,1,1 +access_test_workflow_model_b,access_test_workflow_model_b,model_test_workflow_model_b,,1,1,1,1 +access_test_workflow_model_c,access_test_workflow_model_c,model_test_workflow_model_c,,1,1,1,1 +access_test_workflow_model_d,access_test_workflow_model_d,model_test_workflow_model_d,,1,1,1,1 +access_test_workflow_model_e,access_test_workflow_model_e,model_test_workflow_model_e,,1,1,1,1 +access_test_workflow_model_f,access_test_workflow_model_f,model_test_workflow_model_f,,1,1,1,1 +access_test_workflow_model_g,access_test_workflow_model_g,model_test_workflow_model_g,,1,1,1,1 +access_test_workflow_model_h,access_test_workflow_model_h,model_test_workflow_model_h,,1,1,1,1 +access_test_workflow_model_i,access_test_workflow_model_i,model_test_workflow_model_i,,1,1,1,1 +access_test_workflow_model_j,access_test_workflow_model_j,model_test_workflow_model_j,,1,1,1,1 +access_test_workflow_model_k,access_test_workflow_model_k,model_test_workflow_model_k,,1,1,1,1 +access_test_workflow_model_l,access_test_workflow_model_l,model_test_workflow_model_l,,1,1,1,1 diff --git a/openerp/tools/translate.py b/openerp/tools/translate.py index 4a055950c46..f82fa4b87ad 100644 --- a/openerp/tools/translate.py +++ b/openerp/tools/translate.py @@ -684,7 +684,7 @@ def trans_generate(lang, modules, cr): except AttributeError, exc: _logger.error("name error in %s: %s", xml_name, str(exc)) continue - objmodel = registry[obj.model] + objmodel = registry.get(obj.model) if not objmodel or not field_name in objmodel._columns: continue field_def = objmodel._columns[field_name]