[MERGE] trunk-fix-mail-mail-rules-tde: 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. bzr revid: abo@openerp.com-20120928173657-2a25tw1ewc7ugyr3
This commit is contained in:
commit
0e8f9e3549
|
@ -195,7 +195,7 @@ class res_company(osv.osv):
|
|||
]
|
||||
|
||||
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').browse(cr, SUPERUSER_ID, uid, context=context)
|
||||
for rule in proxy.browse(cr, uid, ids, context):
|
||||
if eval(rule.expression, {'context': context, 'user': user}):
|
||||
return rule.company_dest_id.id
|
||||
|
|
|
@ -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 @@ from lxml import etree
|
|||
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 @@ class res_partner(osv.osv, format_address):
|
|||
- 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 @@ class res_partner(osv.osv, format_address):
|
|||
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 <r.g@grosbedon.fr>"``"""
|
||||
assert email, 'an email is required for find_or_create to work'
|
||||
|
|
|
@ -52,7 +52,7 @@ class groups(osv.osv):
|
|||
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 @@ class groups(osv.osv):
|
|||
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 @@ class res_users(osv.osv):
|
|||
|
||||
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 @@ class res_users(osv.osv):
|
|||
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 @@ class res_users(osv.osv):
|
|||
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', '__last_update']
|
||||
|
||||
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 fields and (ids == [uid] or ids == uid):
|
||||
for key in fields:
|
||||
if not (key in self.SELF_READABLE_FIELDS or key.startswith('context_')):
|
||||
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 @@ class res_users(osv.osv):
|
|||
"""
|
||||
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).
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue