[MERGE] Sunc with addons/trunk.
[odoo/odoo.git] / addons / mail / tests / test_mail_access_rights.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Business Applications
5 #    Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 from openerp.addons.mail.tests import test_mail_mockup
23 from osv.orm import except_orm
24
25
26 class test_mail_access_rights(test_mail_mockup.TestMailMockups):
27
28     def setUp(self):
29         super(test_mail_access_rights, self).setUp()
30         cr, uid = self.cr, self.uid
31         self.mail_group = self.registry('mail.group')
32         self.mail_message = self.registry('mail.message')
33         self.mail_notification = self.registry('mail.notification')
34         self.res_users = self.registry('res.users')
35         self.res_groups = self.registry('res.groups')
36         self.res_partner = self.registry('res.partner')
37
38         # create a 'pigs' group that will be used through the various tests
39         self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
40             {'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
41
42         # Find Employee group
43         group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
44         self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
45
46         # Create Bert (without groups) and Raoul( employee)
47         self.user_bert_id = self.res_users.create(cr, uid, {'name': 'Bert Tartopoils', 'login': 'bert', 'groups_id': [(6, 0, [])]})
48         self.user_raoul_id = self.res_users.create(cr, uid, {'name': 'Raoul Grosbedon', 'login': 'raoul', 'groups_id': [(6, 0, [self.group_employee_id])]})
49         self.user_bert = self.res_users.browse(cr, uid, self.user_bert_id)
50         self.partner_bert_id = self.user_bert.partner_id.id
51         self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id)
52         self.partner_raoul_id = self.user_raoul.partner_id.id
53
54     def test_00_mail_message_search_access_rights(self):
55         """ Test mail_message search override about access rights. """
56         cr, uid, group_pigs_id = self.cr, self.uid, self.group_pigs_id
57         partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
58         user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
59         # Data: comment subtype for mail.message creation
60         ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'mail', 'mt_comment')
61         subtype_id = ref and ref[1] or False
62
63         # Data: Birds group, private
64         group_birds_id = self.mail_group.create(self.cr, self.uid, {'name': 'Birds', 'public': 'private'})
65         # Data: raoul is member of Pigs
66         self.mail_group.message_subscribe(cr, uid, [group_pigs_id], [partner_raoul_id])
67         # Data: various author_ids, partner_ids, documents
68         msg_id1 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A', 'subtype_id': subtype_id})
69         msg_id2 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B', 'partner_ids': [(6, 0, [partner_bert_id])], 'subtype_id': subtype_id})
70         msg_id3 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'subtype_id': subtype_id})
71         msg_id4 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_bert_id])], 'subtype_id': subtype_id})
72         msg_id5 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+R Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_raoul_id])], 'subtype_id': subtype_id})
73         msg_id6 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Birds', 'model': 'mail.group', 'res_id': group_birds_id, 'subtype_id': subtype_id})
74         msg_id7 = self.mail_message.create(cr, user_bert_id, {'subject': '_Test', 'body': 'B', 'subtype_id': subtype_id})
75         msg_id8 = self.mail_message.create(cr, user_bert_id, {'subject': '_Test', 'body': 'B+R', 'partner_ids': [(6, 0, [partner_raoul_id])], 'subtype_id': subtype_id})
76
77         # Test: Bert: 2 messages that have Bert in partner_ids + 2 messages as author
78         msg_ids = self.mail_message.search(cr, user_bert_id, [('subject', 'like', '_Test')])
79         self.assertEqual(set([msg_id2, msg_id4, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed')
80         # Test: Raoul: 3 messages on Pigs Raoul can read (employee can read group with default values), 0 on Birds (private group)
81         msg_ids = self.mail_message.search(cr, user_raoul_id, [('subject', 'like', '_Test'), ('body', 'like', 'A')])
82         self.assertEqual(set([msg_id3, msg_id4, msg_id5]), set(msg_ids), 'mail_message search failed')
83         # Test: Admin: all messages
84         msg_ids = self.mail_message.search(cr, uid, [('subject', 'like', '_Test')])
85         self.assertEqual(set([msg_id1, msg_id2, msg_id3, msg_id4, msg_id5, msg_id6, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed')
86
87     def test_05_mail_message_read_access_rights(self):
88         """ Test basic mail_message read access rights. """
89         cr, uid = self.cr, self.uid
90         partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
91         user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
92
93         # Prepare groups: Pigs (employee), Jobs (public)
94         self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message')
95         self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
96
97         # ----------------------------------------
98         # CASE1: Bert, basic mail.message read access
99         # ----------------------------------------
100
101         # Do: create a new mail.message
102         message_id = self.mail_message.create(cr, uid, {'body': 'My Body'})
103         # Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
104         self.assertRaises(except_orm, self.mail_message.read,
105             cr, user_bert_id, message_id)
106         # Do: message is pushed to Bert
107         notif_id = self.mail_notification.create(cr, uid, {'message_id': message_id, 'partner_id': partner_bert_id})
108         # Test: Bert reads the message, ok because notification pushed
109         self.mail_message.read(cr, user_bert_id, message_id)
110         # Do: remove notification
111         self.mail_notification.unlink(cr, uid, notif_id)
112         # Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
113         self.assertRaises(except_orm, self.mail_message.read,
114             cr, self.user_bert_id, message_id)
115         # Do: Bert is now the author
116         self.mail_message.write(cr, uid, [message_id], {'author_id': partner_bert_id})
117         # Test: Bert reads the message, ok because Bert is the author
118         self.mail_message.read(cr, user_bert_id, message_id)
119         # Do: Bert is not the author anymore
120         self.mail_message.write(cr, uid, [message_id], {'author_id': partner_raoul_id})
121         # Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
122         self.assertRaises(except_orm, self.mail_message.read,
123             cr, user_bert_id, message_id)
124         # Do: message is attached to a document Bert can read, Jobs
125         self.mail_message.write(cr, uid, [message_id], {'model': 'mail.group', 'res_id': self.group_jobs_id})
126         # Test: Bert reads the message, ok because linked to a doc he is allowed to read
127         self.mail_message.read(cr, user_bert_id, message_id)
128         # Do: message is attached to a document Bert cannot read, Pigs
129         self.mail_message.write(cr, uid, [message_id], {'model': 'mail.group', 'res_id': self.group_pigs_id})
130         # Test: Bert reads the message, crash because not notification/not in doc followers/not read on doc
131         self.assertRaises(except_orm, self.mail_message.read,
132             cr, user_bert_id, message_id)
133
134     def test_10_mail_flow_access_rights(self):
135         """ Test a Chatter-looks alike flow. """
136         cr, uid = self.cr, self.uid
137         mail_compose = self.registry('mail.compose.message')
138         partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
139         user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
140
141         # Prepare groups: Pigs (employee), Jobs (public)
142         self.mail_group.message_post(cr, uid, self.group_pigs_id, body='Message')
143         self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
144
145         # ----------------------------------------
146         # CASE1: Bert, without groups
147         # ----------------------------------------
148         # Do: Bert creates a group, should crash because perm_create only for employees
149         self.assertRaises(except_orm,
150                           self.mail_group.create,
151                           cr, user_bert_id, {'name': 'Bert\'s Group'})
152
153         # Do: Bert reads Jobs basic fields, ok because public = read access on the group
154         self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['name', 'description'])
155         # Do: Bert browse Pigs, ok (no direct browse of partners)
156         self.mail_group.browse(cr, user_bert_id, self.group_jobs_id)
157         # Do: Bert reads Jobs messages, ok because read access on the group => read access on its messages
158         jobs_message_ids = self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['message_ids'])['message_ids']
159         self.mail_message.read(cr, user_bert_id, jobs_message_ids)
160         # Do: Bert reads Jobs followers, ko because partner are accessible to employees or partner manager
161         jobs_followers_ids = self.mail_group.read(cr, user_bert_id, self.group_jobs_id, ['message_follower_ids'])['message_follower_ids']
162         self.assertRaises(except_orm,
163                           self.res_partner.read,
164                           cr, user_bert_id, jobs_followers_ids)
165         # Do: Bert comments Jobs, ko because no write access on the group and not in the followers
166         self.assertRaises(except_orm,
167                           self.mail_group.message_post,
168                           cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
169         # Do: add Bert to jobs followers
170         self.mail_group.message_subscribe(cr, uid, [self.group_jobs_id], [partner_bert_id])
171         # Do: Bert comments Jobs, ok because he is now in the followers
172         self.mail_group.message_post(cr, user_bert_id, self.group_jobs_id, body='I love Pigs')
173
174         # Do: Bert reads Pigs, should crash because mail.group security=groups only for employee group
175         self.assertRaises(except_orm,
176                           self.mail_group.read,
177                           cr, user_bert_id, self.group_pigs_id)
178
179         # Do: Bert create a mail.compose.message record, because he uses the wizard
180         compose_id = mail_compose.create(cr, user_bert_id,
181             {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': []},
182             # {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': [(4, p_c_id), (4, p_d_id)]},
183             {'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_jobs_id})
184         mail_compose.send_mail(cr, user_bert_id, [compose_id])
185
186         self.user_demo_id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')[1]
187         compose_id = mail_compose.create(cr, self.user_demo_id,
188             {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': []},
189             # {'subject': 'Subject', 'body_text': 'Body text', 'partner_ids': [(4, p_c_id), (4, p_d_id)]},
190             {'default_composition_mode': 'comment', 'default_model': 'mail.group', 'default_res_id': self.group_jobs_id})
191         mail_compose.send_mail(cr, self.user_demo_id, [compose_id])
192
193         # ----------------------------------------
194         # CASE2: Raoul, employee
195         # ----------------------------------------
196         # Do: Bert read Pigs, ok because public
197         self.mail_group.read(cr, user_raoul_id, self.group_pigs_id)
198         # Do: Bert read Jobs, ok because group_public_id = employee
199         self.mail_group.read(cr, user_raoul_id, self.group_jobs_id)