[FIX] website_sale: prevent compute search to be run in sudo

Before this commit, when accessing an user's pricelist, it would raise a 500
error in multi-company environment.
Indeed, when doing `self.env.user.partner_id.property_product_pricelist`, even
if self.env is not un sudo mode, the compute from `property_product_pricelist`
is executed as sudo. Since this method is then doing a `search()`, it won't use
the multi-company pricelist ir.rule. It will return all the pricelist,
including the ones from other companies.
Then, when trying to read that pricelist, it will raise an access error.

Now, we correctly execute the compute (and so the search) in the user env, it
won't get pricelists from other companies.
This commit is contained in:
Romain Derie
2019-03-14 10:28:02 +00:00
parent a5a5a57e48
commit 9608d4551d
2 changed files with 25 additions and 2 deletions
+2 -2
View File
@@ -68,7 +68,7 @@ class Website(models.Model):
if not show_visible or group_pricelists.selectable or group_pricelists.id in (current_pl, order_pl):
pricelists |= group_pricelists
partner = self.env.user.partner_id
partner = self.env.user.partner_id.sudo(user=self.env.user)
is_public = self.user_id.id == self.env.user.id
if not is_public and (not pricelists or (partner_pl or partner.property_product_pricelist.id) != website_pl):
# `property_product_pricelist` is already multi-website compliant
@@ -104,7 +104,7 @@ class Website(models.Model):
isocountry = request and request.session.geoip and request.session.geoip.get('country_code') or False
partner = self.env.user.partner_id
last_order_pl = partner.last_website_so_id.pricelist_id
partner_pl = partner.property_product_pricelist
partner_pl = partner.sudo(user=self.env.user).property_product_pricelist
pricelists = website._get_pl_partner_order(isocountry, show_visible,
website.user_id.sudo().partner_id.property_product_pricelist.id,
request and request.session.get('website_sale_current_pl') or None,
@@ -136,6 +136,29 @@ def simulate_frontend_context(self, website_id=1):
self.addCleanup(patcher.stop)
class TestWebsitePriceListHttp(HttpCase):
def test_get_pricelist_available_multi_company(self):
''' Test that the `property_product_pricelist` of `res.partner` is not
computed as SUPERUSER_ID.
Indeed, `property_product_pricelist` is a _compute that ends up
doing a search on `product.pricelist` that woule bypass the
pricelist multi-company `ir.rule`. Then it would return pricelists
from another company and the code would raise an access error when
reading that `property_product_pricelist`.
'''
test_company = self.env['res.company'].create({'name': 'Test Company'})
self.env['product.pricelist'].create({
'name': 'Backend Pricelist For "Test Company"',
'website_id': False,
'company_id': test_company.id,
'sequence': 1,
})
self.authenticate('portal', 'portal')
r = self.url_open('/shop')
self.assertEqual(r.status_code, 200, "The page should not raise an access error because of reading pricelists from other companies")
class TestWebsitePriceListMultiCompany(TransactionCase):
def setUp(self):
''' Create a basic multi-company pricelist environment: