[IMP] models: inherited fields are related fields read as the current user
authorRaphael Collet <rco@openerp.com>
Tue, 2 Sep 2014 08:50:52 +0000 (10:50 +0200)
committerRaphael Collet <rco@openerp.com>
Thu, 4 Sep 2014 14:10:48 +0000 (16:10 +0200)
Add an attribute 'related_sudo' (True by default) for related fields.
A related field is computed as superuser if related_sudo is True.

Add explicit related fields 'name' and 'email' on 'res.users', as these should
be readable by the public user with module website_forum.

openerp/addons/base/res/res_users.py
openerp/fields.py
openerp/models.py

index 023bccb..a0e0bd1 100644 (file)
@@ -188,6 +188,11 @@ class res_users(osv.osv):
         'company_ids':fields.many2many('res.company','res_company_users_rel','user_id','cid','Companies'),
     }
 
+    # overridden inherited fields to bypass access rights, in case you have
+    # access to the user but not its corresponding partner
+    name = openerp.fields.Char(related='partner_id.name')
+    email = openerp.fields.Char(related='partner_id.email')
+
     def on_change_login(self, cr, uid, ids, login, context=None):
         if login and tools.single_email_re.match(login):
             return {'value': {'email': login}}
index d0055eb..3c4744a 100644 (file)
@@ -280,6 +280,7 @@ class Field(object):
     inverse = None              # inverse(recs) inverses field on recs
     search = None               # search(recs, operator, value) searches on self
     related = None              # sequence of field names, for related fields
+    related_sudo = True         # whether related fields should be read as admin
     company_dependent = False   # whether `self` is company-dependent (property field)
     default = None              # default value
 
@@ -427,13 +428,16 @@ class Field(object):
 
     def _compute_related(self, records):
         """ Compute the related field `self` on `records`. """
-        for record, sudo_record in zip(records, records.sudo()):
-            # bypass access rights check when traversing the related path
-            value = sudo_record if record.id else record
-            # traverse the intermediate fields, and keep at most one record
+        # when related_sudo, bypass access rights checks when reading values
+        others = records.sudo() if self.related_sudo else records
+        for record, other in zip(records, others):
+            if not record.id:
+                # draft record, do not switch to another environment
+                other = record
+            # traverse the intermediate fields; follow the first record at each step
             for name in self.related[:-1]:
-                value = value[name][:1]
-            record[self.name] = value[self.related[-1]]
+                other = other[name][:1]
+            record[self.name] = other[self.related[-1]]
 
     def _inverse_related(self, records):
         """ Inverse the related field `self` on `records`. """
index 33bf9ba..ef5c2bb 100644 (file)
@@ -2937,8 +2937,11 @@ class BaseModel(object):
         for parent_model, parent_field in reversed(cls._inherits.items()):
             for attr, field in cls.pool[parent_model]._fields.iteritems():
                 if attr not in cls._fields:
-                    new_field = field.copy(related=(parent_field, attr), _origin=field)
-                    cls._add_field(attr, new_field)
+                    cls._add_field(attr, field.copy(
+                        related=(parent_field, attr),
+                        related_sudo=False,
+                        _origin=field,
+                    ))
 
         cls._inherits_reload_src()