1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.sale.tests.common import TestSaleCommon
from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.tests import HttpCase, tagged
@tagged('post_install', '-at_install')
class TestAccessRights(TestSaleCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.company_data['default_user_salesman_2'] = cls.env['res.users'].with_context(no_reset_password=True).create({
'name': 'default_user_salesman_2',
'login': 'default_user_salesman_2.comp%s' % cls.company_data['company'].id,
'email': 'default_user_salesman_2@example.com',
'signature': '--\nMark',
'notification_type': 'email',
'groups_id': [(6, 0, cls.env.ref('sales_team.group_sale_salesman').ids)],
'company_ids': [(6, 0, cls.company_data['company'].ids)],
'company_id': cls.company_data['company'].id,
})
# Create the SO with a specific salesperson
cls.order = cls.env['sale.order'].with_context(tracking_disable=True).create({
'partner_id': cls.partner_a.id,
'user_id': cls.company_data['default_user_salesman'].id
})
def test_access_sales_manager(self):
""" Test sales manager's access rights """
SaleOrder = self.env['sale.order'].with_context(tracking_disable=True)
# Manager can see the SO which is assigned to another salesperson
self.order.read()
# Manager can change a salesperson of the SO
self.order.write({'user_id': self.company_data['default_user_salesman'].id})
# Manager can create the SO for other salesperson
sale_order = SaleOrder.create({
'partner_id': self.partner_a.id,
'user_id': self.company_data['default_user_salesman'].id
})
self.assertIn(sale_order.id, SaleOrder.search([]).ids, 'Sales manager should be able to create the SO of other salesperson')
# Manager can confirm the SO
sale_order.action_confirm()
# Manager can not delete confirmed SO
with self.assertRaises(UserError):
sale_order.unlink()
# Manager can delete the SO of other salesperson if SO is in 'draft' or 'cancel' state
self.order.unlink()
self.assertNotIn(self.order.id, SaleOrder.search([]).ids, 'Sales manager should be able to delete the SO')
# Manager can create a Sales Team
india_channel = self.env['crm.team'].with_context(tracking_disable=True).create({
'name': 'India',
})
self.assertIn(india_channel.id, self.env['crm.team'].search([]).ids, 'Sales manager should be able to create a Sales Team')
# Manager can edit a Sales Team
india_channel.write({'name': 'new_india'})
self.assertEqual(india_channel.name, 'new_india', 'Sales manager should be able to edit a Sales Team')
# Manager can delete a Sales Team
india_channel.unlink()
self.assertNotIn(india_channel.id, self.env['crm.team'].search([]).ids, 'Sales manager should be able to delete a Sales Team')
def test_access_sales_person(self):
""" Test Salesperson's access rights """
# Salesperson can see only their own sales order
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_salesman_2']).read()
# Now assign the SO to themselves
self.order.write({'user_id': self.company_data['default_user_salesman_2'].id})
self.order.with_user(self.company_data['default_user_salesman_2']).read()
# Salesperson can change a Sales Team of SO
self.order.with_user(self.company_data['default_user_salesman_2']).write({'team_id': self.company_data['default_sale_team'].id})
# Salesperson can't create the SO of other salesperson
with self.assertRaises(AccessError):
self.env['sale.order'].with_user(self.company_data['default_user_salesman_2']).create({
'partner_id': self.partner_a.id,
'user_id': self.company_data['default_user_salesman'].id
})
# Salesperson can't delete the SO
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_salesman_2']).unlink()
# Salesperson can confirm the SO
self.order.with_user(self.company_data['default_user_salesman_2']).action_confirm()
def test_access_portal_user(self):
""" Test portal user's access rights """
# Portal user can see the confirmed SO for which they are assigned as a customer
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_portal']).read()
self.order.partner_id = self.company_data['default_user_portal'].partner_id
self.order.action_confirm()
# Portal user can't edit the SO
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_portal']).write({'team_id': self.company_data['default_sale_team'].id})
# Portal user can't create the SO
with self.assertRaises(AccessError):
self.env['sale.order'].with_user(self.company_data['default_user_portal']).create({
'partner_id': self.partner_a.id,
})
# Portal user can't delete the SO which is in 'draft' or 'cancel' state
self.order.action_cancel()
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_portal']).unlink()
def test_access_employee(self):
""" Test classic employee's access rights """
# Employee can't see any SO
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_employee']).read()
# Employee can't edit the SO
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_employee']).write({'team_id': self.company_data['default_sale_team'].id})
# Employee can't create the SO
with self.assertRaises(AccessError):
self.env['sale.order'].with_user(self.company_data['default_user_employee']).create({
'partner_id': self.partner_a.id,
})
# Employee can't delete the SO
with self.assertRaises(AccessError):
self.order.with_user(self.company_data['default_user_employee']).unlink()
@tagged('post_install', '-at_install')
class TestAccessRightsControllers(HttpCase):
def test_access_controller(self):
portal_so = self.env.ref("sale.portal_sale_order_2").sudo()
portal_so._portal_ensure_token()
token = portal_so.access_token
private_so = self.env.ref("sale.sale_order_1")
self.authenticate(None, None)
# Test public user can't print an order without a token
req = self.url_open(
url='/my/orders/%s?report_type=pdf' % portal_so.id,
allow_redirects=False,
)
self.assertEqual(req.status_code, 302)
# or with a random token
req = self.url_open(
url='/my/orders/%s?access_token=%s&report_type=pdf' % (
portal_so.id,
"foo",
),
allow_redirects=False,
)
self.assertEqual(req.status_code, 302)
# but works fine with the right token
req = self.url_open(
url='/my/orders/%s?access_token=%s&report_type=pdf' % (
portal_so.id,
token,
),
allow_redirects=False,
)
self.assertEqual(req.status_code, 200)
self.authenticate("portal", "portal")
# do not need the token when logged in
req = self.url_open(
url='/my/orders/%s?report_type=pdf' % portal_so.id,
allow_redirects=False,
)
self.assertEqual(req.status_code, 200)
# but still can't access another order
req = self.url_open(
url='/my/orders/%s?report_type=pdf' % private_so.id,
allow_redirects=False,
)
self.assertEqual(req.status_code, 302)
|