[IMP] mail: add mailing.activity tests based on _search operation

This commit adds some tests on mailing.activity to ensure _searching is only
possible when the user has access to the underlying document.

Query count for 'test_adv_activity_mixin' had to be slightly adapted (+1) since
calling 'action_close' in turn calls 'activity_search' that calls 'search' on
mail.activity that now runs an additional query (see '_search' override
docstring).

Task-2272475
This commit is contained in:
Aurélien Warnon
2021-06-02 07:18:06 +00:00
parent 832c3e8333
commit cbf4f50727
3 changed files with 72 additions and 1 deletions
+61
View File
@@ -453,6 +453,67 @@ class MailActivity(models.Model):
{'type': 'activity_updated', 'activity_deleted': True})
return super(MailActivity, self).unlink()
@api.model
def _search(self, args, offset=0, limit=None, order=None, count=False, access_rights_uid=None):
""" Override that adds specific access rights of mail.activity, to remove
ids uid could not see according to our custom rules. Please refer to
_filter_access_rules_remaining for more details about those rules.
The method is inspired by what has been done on mail.message. """
# Rules do not apply to administrator
if self.env.is_superuser():
return super(MailActivity, self)._search(
args, offset=offset, limit=limit, order=order,
count=count, access_rights_uid=access_rights_uid)
# Perform a super with count as False, to have the ids, not a counter
ids = super(MailActivity, self)._search(
args, offset=offset, limit=limit, order=order,
count=False, access_rights_uid=access_rights_uid)
if not ids and count:
return 0
elif not ids:
return ids
# check read access rights before checking the actual rules on the given ids
super(MailActivity, self.with_user(access_rights_uid or self._uid)).check_access_rights('read')
self.flush(['res_model', 'res_id'])
activities_to_check = []
for sub_ids in self._cr.split_for_in_conditions(ids):
self._cr.execute("""
SELECT DISTINCT activity.id, activity.res_model, activity.res_id
FROM "%s" activity
WHERE activity.id = ANY (%%(ids)s)""" % self._table, dict(ids=list(sub_ids)))
activities_to_check = self._cr.dictfetchall()
activity_to_documents = {}
for activity in activities_to_check:
activity_to_documents.setdefault(activity['res_model'], list()).append(activity['res_id'])
allowed_ids = []
for doc_model, doc_ids in activity_to_documents.items():
# fall back on related document access right checks. Use the same as defined for mail.thread
# if available; otherwise fall back on read
if hasattr(self.env[doc_model], '_mail_post_access'):
doc_operation = self.env[doc_model]._mail_post_access
else:
doc_operation = 'read'
DocumentModel = self.env[doc_model].with_user(access_rights_uid or self._uid)
right = DocumentModel.check_access_rights(doc_operation, raise_exception=False)
if right:
valid_docs = DocumentModel.browse(doc_ids)._filter_access_rules(doc_operation)
allowed_ids += [
activity['id'] for activity in activities_to_check
if activity['res_model'] == doc_model and activity['res_id'] in valid_docs.ids]
if count:
return len(allowed_ids)
else:
# re-construct a list based on ids, because 'allowed_ids' does not keep the original order
id_list = [id for id in ids if id in allowed_ids]
return id_list
def name_get(self):
res = []
for record in self:
@@ -77,6 +77,16 @@ class TestActivityRights(TestActivityCommon):
'summary': 'Summary',
})
# can _search activities if access to the document
self.env['mail.activity'].with_user(self.user_employee)._search(
[('id', '=', test_activity.id)], count=False)
# cannot _search activities if no access to the document
with patch.object(MailTestActivity, 'check_access_rights', autospec=True, side_effect=_employee_crash):
with self.assertRaises(exceptions.AccessError):
searched_activity = self.env['mail.activity'].with_user(self.user_employee)._search(
[('id', '=', test_activity.id)], count=False)
# cannot read activities if no access to the document
with patch.object(MailTestActivity, 'check_access_rights', autospec=True, side_effect=_employee_crash):
with self.assertRaises(exceptions.AccessError):
+1 -1
View File
@@ -249,7 +249,7 @@ class TestMailAPIPerformance(BaseMailPerformance):
record.write({'name': 'Dupe write'})
with self.assertQueryCount(__system__=17, emp=19):
with self.assertQueryCount(__system__=17, emp=20):
record.action_close('Dupe feedback')
self.assertEqual(record.activity_ids, self.env['mail.activity'])