[IMP] mail.message: check is now a check_access_rule override, allowing to remove explicit calls. Moved mail.notification inheritance in mail.message directly into mail.notification, because we are in the same module (no need to separate things too much when in the same module).
bzr revid: tde@openerp.com-20120831090120-s56984dg6wpbs0li
This commit is contained in:
parent
660553d404
commit
3cc186cd41
|
@ -59,6 +59,8 @@ class mail_notification(osv.Model):
|
|||
'partner_id': fields.many2one('res.partner', string='Contact',
|
||||
ondelete='cascade', required=True, select=1),
|
||||
'read': fields.boolean('Read'),
|
||||
'message_id': fields.many2one('mail.message', string='Message',
|
||||
ondelete='cascade', required=True, select=1),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -72,6 +74,11 @@ class mail_notification(osv.Model):
|
|||
return super(mail_notification, self).create(cr, uid, vals, context=context)
|
||||
return False
|
||||
|
||||
def set_message_read(self, cr, uid, msg_id, context=None):
|
||||
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
notif_ids = self.search(cr, uid, [('partner_id', '=', partner_id), ('message_id', '=', msg_id)], context=context)
|
||||
return self.write(cr, uid, notif_ids, {'read': True}, context=context)
|
||||
|
||||
def notify(self, cr, uid, partner_ids, msg_id, context=None):
|
||||
""" Send by email the notification depending on the user preferences """
|
||||
context = context or {}
|
||||
|
|
|
@ -34,11 +34,8 @@ def decode(text):
|
|||
return ''.join([tools.ustr(x[0], x[1]) for x in text])
|
||||
|
||||
class mail_message(osv.Model):
|
||||
"""Model holding messages: system notification (replacing res.log
|
||||
notifications), comments (for OpenChatter feature). This model also
|
||||
provides facilities to parse new email messages. Type of messages are
|
||||
differentiated using the 'type' column. """
|
||||
|
||||
""" Messages model: system notification (replacing res.log notifications),
|
||||
comments (OpenChatter discussion) and incoming emails. """
|
||||
_name = 'mail.message'
|
||||
_description = 'Message'
|
||||
_inherit = ['ir.needaction_mixin']
|
||||
|
@ -76,9 +73,9 @@ class mail_message(osv.Model):
|
|||
return res
|
||||
|
||||
def _search_unread(self, cr, uid, obj, name, domain, context=None):
|
||||
""" Search for messages unread by the current user. """
|
||||
read_value = not domain[0][2]
|
||||
read_cond = '' if read_value else '!= true'
|
||||
""" Search for messages unread by the current user. Condition is
|
||||
inversed because we search unread message on a read column. """
|
||||
read_cond = '' if not domain[0][2] else '!= true'
|
||||
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
cr.execute(""" SELECT mail_message.id \
|
||||
FROM mail_message \
|
||||
|
@ -87,10 +84,7 @@ class mail_message(osv.Model):
|
|||
WHERE mail_notification.partner_id = %%s AND \
|
||||
mail_notification.read %s \
|
||||
""" % read_cond, (partner_id,) )
|
||||
res = cr.fetchall()
|
||||
message_ids = [r[0] for r in res]
|
||||
return [('id', 'in', message_ids)]
|
||||
|
||||
return [('id', 'in', [r[0] for r in cr.fetchall()])]
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
# name_get may receive int id instead of an id list
|
||||
|
@ -103,9 +97,8 @@ class mail_message(osv.Model):
|
|||
return res
|
||||
|
||||
_columns = {
|
||||
# should we keep a distinction between email and comment ?
|
||||
'type': fields.selection([
|
||||
('email', 'email'),
|
||||
('email', 'Email'),
|
||||
('comment', 'Comment'),
|
||||
('notification', 'System notification'),
|
||||
], 'Type',
|
||||
|
@ -146,7 +139,6 @@ class mail_message(osv.Model):
|
|||
'author_id': _get_default_author
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------
|
||||
# Message loading for web interface
|
||||
#------------------------------------------------------
|
||||
|
@ -261,12 +253,11 @@ class mail_message(osv.Model):
|
|||
break
|
||||
|
||||
# Flatten the result
|
||||
if thread_level > 0:
|
||||
result = self.message_read_tree_flatten(cr, uid, result, 0, thread_level, context=context)
|
||||
# if thread_level > 0:
|
||||
# result = self.message_read_tree_flatten(cr, uid, result, 0, thread_level, context=context)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
#------------------------------------------------------
|
||||
# Email api
|
||||
#------------------------------------------------------
|
||||
|
@ -276,52 +267,47 @@ class mail_message(osv.Model):
|
|||
if not cr.fetchone():
|
||||
cr.execute("""CREATE INDEX mail_message_model_res_id_idx ON mail_message (model, res_id)""")
|
||||
|
||||
def check(self, cr, uid, ids, mode, context=None):
|
||||
"""
|
||||
You can read/write a message if:
|
||||
- you received it (a notification exists) or
|
||||
- you can read the related document (res_model, res_id)
|
||||
If a message is not attached to a document, normal access rights on
|
||||
the mail.message object apply.
|
||||
"""
|
||||
if not ids:
|
||||
return
|
||||
def check_access_rule(self, cr, uid, ids, operation, context=None):
|
||||
""" mail.message access rule check
|
||||
- message received (a notification exists) -> ok
|
||||
- check rules of related document if exists
|
||||
- fallback on normal mail.message check """
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
|
||||
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
|
||||
# check messages for which you have a notification
|
||||
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
not_obj = self.pool.get('mail.notification')
|
||||
not_ids = not_obj.search(cr, uid, [
|
||||
('partner_id', '=', partner_id),
|
||||
('message_id', 'in', ids),
|
||||
], context=context)
|
||||
for notification in not_obj.browse(cr, uid, not_ids, context=context):
|
||||
if notification.message_id.id in ids:
|
||||
pass
|
||||
# FP Note: we should put this again !!!
|
||||
#ids.remove(notification.message_id.id)
|
||||
notified_ids = [notification.message_id.id for notification in not_obj.browse(cr, uid, not_ids, context=context)
|
||||
if notification.message_id.id in ids]
|
||||
|
||||
# check messages according to related documents
|
||||
res_ids = {}
|
||||
cr.execute('SELECT DISTINCT model, res_id FROM mail_message WHERE id = ANY (%s)', (ids,))
|
||||
for rmod, rid in cr.fetchall():
|
||||
# check messages linked to an existing document
|
||||
model_record_ids = {}
|
||||
document_ids = []
|
||||
cr.execute('SELECT DISTINCT id, model, res_id FROM mail_message WHERE id = ANY (%s)', (ids,))
|
||||
for id, rmod, rid in cr.fetchall():
|
||||
if not (rmod and rid):
|
||||
continue
|
||||
res_ids.setdefault(rmod,set()).add(rid)
|
||||
document_ids.append(id)
|
||||
model_record_ids.setdefault(rmod,set()).add(rid)
|
||||
for model, mids in model_record_ids.items():
|
||||
model_obj = self.pool.get(model)
|
||||
mids = model_obj.exists(cr, uid, mids)
|
||||
model_obj.check_access_rights(cr, uid, operation)
|
||||
model_obj.check_access_rule(cr, uid, mids, operation, context=context)
|
||||
|
||||
ima_obj = self.pool.get('ir.model.access')
|
||||
for model, mids in res_ids.items():
|
||||
mids = self.pool.get(model).exists(cr, uid, mids)
|
||||
ima_obj.check(cr, uid, model, mode)
|
||||
self.pool.get(model).check_access_rule(cr, uid, mids, mode, context=context)
|
||||
# fall back on classic operation for other ids
|
||||
other_ids = set(ids).difference(set(notified_ids), set(document_ids))
|
||||
super(mail_message, self).check_access_rule(cr, uid, other_ids, operation, context=None)
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
if not values.get('message_id') and values.get('res_id') and values.get('model'):
|
||||
values['message_id'] = tools.generate_tracking_message_id('%(model)s-%(res_id)s'% values)
|
||||
newid = super(mail_message, self).create(cr, uid, values, context)
|
||||
self.check(cr, uid, [newid], mode='create', context=context)
|
||||
self.notify(cr, uid, newid, context=context)
|
||||
return newid
|
||||
|
||||
|
@ -344,40 +330,9 @@ class mail_message(osv.Model):
|
|||
partners_to_notify |= extra_notified
|
||||
self.pool.get('mail.notification').notify(cr, uid, list(partners_to_notify), newid, context=context)
|
||||
|
||||
def read(self, cr, uid, ids, fields_to_read=None, context=None, load='_classic_read'):
|
||||
self.check(cr, uid, ids, 'read', context=context)
|
||||
return super(mail_message, self).read(cr, uid, ids, fields_to_read, context, load)
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
"""Overridden to avoid duplicating fields that are unique to each email"""
|
||||
if default is None:
|
||||
default = {}
|
||||
self.check(cr, uid, [id], 'read', context=context)
|
||||
default.update(message_id=False, headers=False)
|
||||
return super(mail_message,self).copy(cr, uid, id, default=default, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
result = super(mail_message, self).write(cr, uid, ids, vals, context)
|
||||
self.check(cr, uid, ids, 'write', context=context)
|
||||
return result
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
self.check(cr, uid, ids, 'unlink', context=context)
|
||||
return super(mail_message, self).unlink(cr, uid, ids, context)
|
||||
|
||||
|
||||
class mail_notification(osv.Model):
|
||||
""" mail_notification is a relational table modeling messages pushed to partners.
|
||||
"""
|
||||
_inherit = 'mail.notification'
|
||||
_columns = {
|
||||
'message_id': fields.many2one('mail.message', string='Message',
|
||||
ondelete='cascade', required=True, select=1),
|
||||
}
|
||||
|
||||
def set_message_read(self, cr, uid, msg_id, context=None):
|
||||
partner_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
notif_ids = self.search(cr, uid, [('partner_id', '=', partner_id), ('message_id', '=', msg_id)], context=context)
|
||||
return self.write(cr, uid, notif_ids, {'read': True}, context=context)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue