Anto has proposed merging 
lp:~openerp-dev/openobject-server/trunk-fix-mail-mail-rules-tde into 
lp:openobject-server.

Requested reviews:
  OpenERP Core Team (openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-fix-mail-mail-rules-tde/+merge/126990

OpenChatter "Rule Yur Daddy" Branch

Fixes some of access rights issues. This server branch features :
- update of res.users model, where the feature allowing to write on its own 
user on WRITABLE_FIELDS is duplicated for reading. This allows for users not 
having read access on res.partner to read some of their data.
-- 
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-fix-mail-mail-rules-tde/+merge/126990
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-server/trunk-fix-mail-mail-rules-tde.
=== modified file 'openerp/addons/base/res/res_company.py'
--- openerp/addons/base/res/res_company.py	2012-09-13 12:20:11 +0000
+++ openerp/addons/base/res/res_company.py	2012-09-28 15:04:25 +0000
@@ -195,11 +195,11 @@
         ]
 
         ids = proxy.search(cr, uid, args, context=context)
-        user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
+        user = self.pool.get('res.users').read(cr, uid, [uid], ['company_id'], context=context)[0]
         for rule in proxy.browse(cr, uid, ids, context):
             if eval(rule.expression, {'context': context, 'user': user}):
                 return rule.company_dest_id.id
-        return user.company_id.id
+        return user['company_id'][0]
 
     @tools.ormcache()
     def _get_company_children(self, cr, uid=None, company=None):

=== modified file 'openerp/addons/base/res/res_partner.py'
--- openerp/addons/base/res/res_partner.py	2012-09-26 13:10:06 +0000
+++ openerp/addons/base/res/res_partner.py	2012-09-28 15:04:25 +0000
@@ -22,6 +22,7 @@
 import math
 import openerp
 from osv import osv, fields
+from openerp import SUPERUSER_ID
 import re
 import tools
 from tools.translate import _
@@ -33,7 +34,7 @@
 class format_address(object):
     def fields_view_get_address(self, cr, uid, arch, context={}):
         user_obj = self.pool.get('res.users')
-        fmt = user_obj.browse(cr, uid, uid,context).company_id.country_id
+        fmt = user_obj.browse(cr, SUPERUSER_ID, uid, context).company_id.country_id
         fmt = fmt and fmt.address_format
         layouts = {
             '%(city)s %(state_code)s\n%(zip)s': """
@@ -396,7 +397,7 @@
             - otherwise: default, everything is set as the name """
         match = re.search(r'([^\s,<@]+@[^>\s,]+)', text)
         if match:
-            email = match.group(1) 
+            email = match.group(1)
             name = text[:text.index(email)].replace('"','').replace('<','').strip()
         else:
             name, email = text, ''
@@ -444,7 +445,7 @@
     def find_or_create(self, cr, uid, email, context=None):
         """ Find a partner with the given ``email`` or use :py:method:`~.name_create`
             to create one
-            
+
             :param str email: email-like string, which should contain at least one email,
                 e.g. ``"Raoul Grosbedon <[email protected]>"``"""
         assert email, 'an email is required for find_or_create to work'

=== modified file 'openerp/addons/base/res/res_users.py'
--- openerp/addons/base/res/res_users.py	2012-09-12 04:35:51 +0000
+++ openerp/addons/base/res/res_users.py	2012-09-28 15:04:25 +0000
@@ -52,7 +52,7 @@
             else:
                 res[g.id] = g.name
         return res
-    
+
     def _search_group(self, cr, uid, obj, name, args, context=None):
         operand = args[0][2]
         operator = args[0][1]
@@ -64,7 +64,7 @@
             group_name = values[1]
             where = ['|',('category_id.name', operator, application_name)] + where
         return where
-    
+
     _columns = {
         'name': fields.char('Name', size=64, required=True, translate=True),
         'users': fields.many2many('res.users', 'res_groups_users_rel', 'gid', 'uid', 'Users'),
@@ -138,7 +138,7 @@
 
     def _get_password(self, cr, uid, ids, arg, karg, context=None):
         return dict.fromkeys(ids, '')
-    
+
     _columns = {
         'id': fields.integer('ID'),
         'login_date': fields.date('Latest connection', select=1),
@@ -193,21 +193,6 @@
         partner_ids = [user.partner_id.id for user in self.browse(cr, uid, ids, context=context)]
         return self.pool.get('res.partner').onchange_address(cr, uid, partner_ids, use_parent_address, parent_id, context=context)
 
-    def read(self,cr, uid, ids, fields=None, context=None, load='_classic_read'):
-        def override_password(o):
-            if 'password' in o and ( 'id' not in o or o['id'] != uid ):
-                o['password'] = '********'
-            return o
-        result = super(res_users, self).read(cr, uid, ids, fields, context, load)
-        canwrite = self.pool.get('ir.model.access').check(cr, uid, 'res.users', 'write', False)
-        if not canwrite:
-            if isinstance(ids, (int, long)):
-                result = override_password(result)
-            else:
-                result = map(override_password, result)
-        return result
-
-
     def _check_company(self, cr, uid, ids, context=None):
         return all(((this.company_id in this.company_ids) or not this.company_ids) for this in self.browse(cr, uid, ids, context))
 
@@ -276,8 +261,34 @@
             return self.pool.get('res.partner').fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
         return super(res_users, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
 
-    # User can write to a few of her own fields (but not her groups for example)
-    SELF_WRITEABLE_FIELDS = ['password', 'signature', 'action_id', 'company_id', 'email', 'name', 'image', 'image_medium', 'image_small']
+    # User can write on a few of his own fields (but not his groups for example)
+    SELF_WRITEABLE_FIELDS = ['password', 'signature', 'action_id', 'company_id', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz']
+    # User can read a few of his own fields
+    SELF_READABLE_FIELDS = ['signature', 'company_id', 'login', 'email', 'name', 'image', 'image_medium', 'image_small', 'lang', 'tz', 'groups_id', 'partner_id']
+
+    def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
+        def override_password(o):
+            if 'password' in o and ('id' not in o or o['id'] != uid):
+                o['password'] = '********'
+            return o
+
+        if (isinstance(ids, (list, tuple)) and ids == [uid]) or ids == uid:
+            for key in fields:
+                if not (key in self.SELF_READABLE_FIELDS or key.startswith('context_') or key in ['__last_update']):
+                    break
+            else:
+                # safe fields only, so we read as super-user to bypass access rights
+                uid = SUPERUSER_ID
+
+        result = super(res_users, self).read(cr, uid, ids, fields=fields, context=context, load=load)
+        canwrite = self.pool.get('ir.model.access').check(cr, uid, 'res.users', 'write', False)
+        if not canwrite:
+            if isinstance(ids, (int, long)):
+                result = override_password(result)
+            else:
+                result = map(override_password, result)
+
+        return result
 
     def write(self, cr, uid, ids, values, context=None):
         if not hasattr(ids, '__iter__'):
@@ -495,14 +506,14 @@
         """
         assert group_ext_id and '.' in group_ext_id, "External ID must be fully qualified"
         module, ext_id = group_ext_id.split('.')
-        cr.execute("""SELECT 1 FROM res_groups_users_rel WHERE uid=%s AND gid IN 
+        cr.execute("""SELECT 1 FROM res_groups_users_rel WHERE uid=%s AND gid IN
                         (SELECT res_id FROM ir_model_data WHERE module=%s AND name=%s)""",
                    (uid, module, ext_id))
         return bool(cr.fetchone())
 
 
 #
-# Extension of res.groups and res.users with a relation for "implied" or 
+# Extension of res.groups and res.users with a relation for "implied" or
 # "inherited" groups.  Once a user belongs to a group, it automatically belongs
 # to the implied groups (transitively).
 #

=== modified file 'openerp/osv/osv.py'
--- openerp/osv/osv.py	2012-09-18 13:04:36 +0000
+++ openerp/osv/osv.py	2012-09-28 15:04:25 +0000
@@ -120,7 +120,9 @@
                     raise except_osv('Database not ready', 'Currently, this database is not fully loaded and can not be used.')
                 return f(self, dbname, *args, **kwargs)
             except orm.except_orm, inst:
-                raise except_osv(inst.name, inst.value)
+                raise
+                # TDE: commented to have more valuable stack traces
+                # raise except_osv(inst.name, inst.value)
             except except_osv:
                 raise
             except IntegrityError, inst:

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to