a4f29735a69173b631f1f318e660c5241116596d
[odoo/odoo.git] / addons / portal_project / tests / test_access_rights.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Business Applications
5 #    Copyright (c) 2013-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.project.tests.test_project_base import TestProjectBase
23 from openerp.exceptions import AccessError
24 from openerp.osv.orm import except_orm
25 from openerp.tools import mute_logger
26
27
28 class TestPortalProjectBase(TestProjectBase):
29
30     def setUp(self):
31         super(TestPortalProjectBase, self).setUp()
32         cr, uid = self.cr, self.uid
33
34         # Find Portal group
35         group_portal_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_portal')
36         self.group_portal_id = group_portal_ref and group_portal_ref[1] or False
37
38         # Find Public group
39         group_public_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_public')
40         self.group_public_id = group_public_ref and group_public_ref[1] or False
41
42         # # Test users to use through the various tests
43         self.user_portal_id = self.res_users.create(cr, uid, {
44             'name': 'Chell Portal',
45             'login': 'chell',
46             'alias_name': 'chell',
47             'groups_id': [(6, 0, [self.group_portal_id])]
48         })
49         self.user_public_id = self.res_users.create(cr, uid, {
50             'name': 'Donovan Public',
51             'login': 'donovan',
52             'alias_name': 'donovan',
53             'groups_id': [(6, 0, [self.group_public_id])]
54         })
55         self.user_manager_id = self.res_users.create(cr, uid, {
56             'name': 'Eustache Manager',
57             'login': 'eustache',
58             'alias_name': 'eustache',
59             'groups_id': [(6, 0, [self.group_project_manager_id])]
60         })
61
62         # Test 'Pigs' project
63         self.project_pigs_id = self.project_project.create(cr, uid, {
64             'name': 'Pigs', 'privacy_visibility': 'public'}, {'mail_create_nolog': True})
65         # Various test tasks
66         self.task_1_id = self.project_task.create(cr, uid, {
67             'name': 'Test1', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
68         self.task_2_id = self.project_task.create(cr, uid, {
69             'name': 'Test2', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
70         self.task_3_id = self.project_task.create(cr, uid, {
71             'name': 'Test3', 'user_id': False, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
72         self.task_4_id = self.project_task.create(cr, uid, {
73             'name': 'Test4', 'user_id': self.user_projectuser_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
74         self.task_5_id = self.project_task.create(cr, uid, {
75             'name': 'Test5', 'user_id': self.user_portal_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
76         self.task_6_id = self.project_task.create(cr, uid, {
77             'name': 'Test6', 'user_id': self.user_public_id, 'project_id': self.project_pigs_id}, {'mail_create_nolog': True})
78
79
80 class TestPortalProject(TestPortalProjectBase):
81     @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
82     def test_00_project_access_rights(self):
83         """ Test basic project access rights, for project and portal_project """
84         cr, uid, pigs_id = self.cr, self.uid, self.project_pigs_id
85
86         # ----------------------------------------
87         # CASE1: public project
88         # ----------------------------------------
89
90         # Do: Alfred reads project -> ok (employee ok public)
91         self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
92         # Test: all project tasks visible
93         task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
94         test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
95         self.assertEqual(set(task_ids), test_task_ids,
96                          'access rights: project user cannot see all tasks of a public project')
97         # Test: all project tasks readable
98         self.project_task.read(cr, self.user_projectuser_id, task_ids, ['name'])
99         # Test: all project tasks writable
100         self.project_task.write(cr, self.user_projectuser_id, task_ids, {'description': 'TestDescription'})
101
102         # Do: Bert reads project -> crash, no group
103         self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
104         # Test: no project task visible
105         self.assertRaises(AccessError, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
106         # Test: no project task readable
107         self.assertRaises(AccessError, self.project_task.read, cr, self.user_none_id, task_ids, ['name'])
108         # Test: no project task writable
109         self.assertRaises(AccessError, self.project_task.write, cr, self.user_none_id, task_ids, {'description': 'TestDescription'})
110
111         # Do: Chell reads project -> ok (portal ok public)
112         self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
113         # Test: all project tasks visible
114         task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
115         self.assertEqual(set(task_ids), test_task_ids,
116                          'access rights: project user cannot see all tasks of a public project')
117         # Test: all project tasks readable
118         self.project_task.read(cr, self.user_portal_id, task_ids, ['name'])
119         # Test: no project task writable
120         self.assertRaises(AccessError, self.project_task.write, cr, self.user_portal_id, task_ids, {'description': 'TestDescription'})
121
122         # Do: Donovan reads project -> ok (public)
123         self.project_project.read(cr, self.user_public_id, [pigs_id], ['state'])
124         # Test: all project tasks visible
125         task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
126         self.assertEqual(set(task_ids), test_task_ids,
127                          'access rights: public user cannot see all tasks of a public project')
128         # Test: all project tasks readable
129         self.project_task.read(cr, self.user_public_id, task_ids, ['name'])
130         # Test: no project task writable
131         self.assertRaises(AccessError, self.project_task.write, cr, self.user_public_id, task_ids, {'description': 'TestDescription'})
132
133         # ----------------------------------------
134         # CASE2: portal project
135         # ----------------------------------------
136         self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'portal'})
137         self.project_project.invalidate_cache(cr, uid)
138
139         # Do: Alfred reads project -> ok (employee ok public)
140         self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
141         # Test: all project tasks visible
142         task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
143         self.assertEqual(set(task_ids), test_task_ids,
144                          'access rights: project user cannot see all tasks of a portal project')
145
146         # Do: Bert reads project -> crash, no group
147         self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
148         # Test: no project task searchable
149         self.assertRaises(AccessError, self.project_task.search, cr, self.user_none_id, [('project_id', '=', pigs_id)])
150
151         # Data: task follower
152         self.project_project.message_subscribe_users(cr, self.user_manager_id, [pigs_id], [self.user_portal_id])
153         self.project_task.message_subscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
154
155         # Do: Chell reads project -> ok (portal ok portal)
156         self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
157
158         # Do: Donovan reads project -> ko (public ko portal)
159         self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
160         # Test: no project task visible
161         task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
162         self.assertFalse(task_ids, 'access rights: public user should not see tasks of a portal project')
163
164         # Data: task follower cleaning
165         self.project_task.message_unsubscribe_users(cr, self.user_projectuser_id, [self.task_1_id, self.task_3_id], [self.user_portal_id])
166
167         # ----------------------------------------
168         # CASE3: employee project
169         # ----------------------------------------
170         self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'employees'})
171         self.project_project.invalidate_cache(cr, uid)
172
173         # Do: Alfred reads project -> ok (employee ok employee)
174         self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
175         # Test: all project tasks visible
176         task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
177         test_task_ids = set([self.task_1_id, self.task_2_id, self.task_3_id, self.task_4_id, self.task_5_id, self.task_6_id])
178         self.assertEqual(set(task_ids), test_task_ids,
179                          'access rights: project user cannot see all tasks of an employees project')
180
181         # Do: Bert reads project -> crash, no group
182         self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
183
184         # Do: Chell reads project -> ko (portal ko employee)
185         self.assertRaises(except_orm, self.project_project.read, cr, self.user_portal_id, [pigs_id], ['state'])
186         # Test: no project task visible + assigned
187         task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
188         self.assertFalse(task_ids, 'access rights: portal user should not see tasks of an employees project, even if assigned')
189
190         # Do: Donovan reads project -> ko (public ko employee)
191         self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
192         # Test: no project task visible
193         task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
194         self.assertFalse(task_ids, 'access rights: public user should not see tasks of an employees project')
195
196         # Do: project user is employee and can create a task
197         tmp_task_id = self.project_task.create(cr, self.user_projectuser_id, {
198             'name': 'Pigs task', 'project_id': pigs_id
199         }, {'mail_create_nolog': True})
200         self.project_task.unlink(cr, self.user_projectuser_id, [tmp_task_id])
201
202         # ----------------------------------------
203         # CASE4: followers project
204         # ----------------------------------------
205         self.project_project.write(cr, uid, [pigs_id], {'privacy_visibility': 'followers'})
206         self.project_project.invalidate_cache(cr, uid)
207
208         # Do: Alfred reads project -> ko (employee ko followers)
209         self.assertRaises(except_orm, self.project_project.read, cr, self.user_projectuser_id, [pigs_id], ['state'])
210         # Test: no project task visible
211         task_ids = self.project_task.search(cr, self.user_projectuser_id, [('project_id', '=', pigs_id)])
212         test_task_ids = set([self.task_4_id])
213         self.assertEqual(set(task_ids), test_task_ids,
214                          'access rights: employee user should not see tasks of a not-followed followers project, only assigned')
215
216         # Do: Bert reads project -> crash, no group
217         self.assertRaises(AccessError, self.project_project.read, cr, self.user_none_id, [pigs_id], ['state'])
218
219         # Do: Chell reads project -> ko (portal ko followers)
220         self.project_project.message_unsubscribe_users(cr, self.user_portal_id, [pigs_id], [self.user_portal_id])
221         self.assertRaises(except_orm, self.project_project.read, cr, self.user_portal_id, [pigs_id], ['state'])
222         # Test: no project task visible
223         task_ids = self.project_task.search(cr, self.user_portal_id, [('project_id', '=', pigs_id)])
224         test_task_ids = set([self.task_5_id])
225         self.assertEqual(set(task_ids), test_task_ids,
226                          'access rights: portal user should not see tasks of a not-followed followers project, only assigned')
227
228         # Do: Donovan reads project -> ko (public ko employee)
229         self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
230         # Test: no project task visible
231         task_ids = self.project_task.search(cr, self.user_public_id, [('project_id', '=', pigs_id)])
232         self.assertFalse(task_ids, 'access rights: public user should not see tasks of a followers project')
233
234         # Data: subscribe Alfred, Chell and Donovan as follower
235         self.project_project.message_subscribe_users(cr, uid, [pigs_id], [self.user_projectuser_id, self.user_portal_id, self.user_public_id])
236         self.project_task.message_subscribe_users(cr, self.user_manager_id, [self.task_1_id, self.task_3_id], [self.user_portal_id, self.user_projectuser_id])
237
238         # Do: Alfred reads project -> ok (follower ok followers)
239         self.project_project.read(cr, self.user_projectuser_id, [pigs_id], ['state'])
240
241         # Do: Chell reads project -> ok (follower ok follower)
242         self.project_project.read(cr, self.user_portal_id, [pigs_id], ['state'])
243
244         # Do: Donovan reads project -> ko (public ko follower even if follower)
245         self.assertRaises(except_orm, self.project_project.read, cr, self.user_public_id, [pigs_id], ['state'])
246
247         # Do: project user is follower of the project and can create a task
248         self.project_task.create(cr, self.user_projectuser_id, {
249             'name': 'Pigs task', 'project_id': pigs_id
250         }, {'mail_create_nolog': True})
251
252         # not follower user should not be able to create a task
253         self.project_project.message_unsubscribe_users(cr, self.user_projectuser_id, [pigs_id], [self.user_projectuser_id])
254         self.assertRaises(except_orm,
255             self.project_task.create, cr, self.user_projectuser_id, {'name': 'Pigs task', 'project_id': pigs_id}, {'mail_create_nolog': True}
256         )
257
258         # Do: project user can create a task without project
259         self.project_task.create(cr, self.user_projectuser_id, {
260             'name': 'Pigs task', 'project_id': False
261         }, {'mail_create_nolog': True})