Skip to content
Permalink
Browse files

[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.
  • Loading branch information...
rdeodoo committed Mar 12, 2019
1 parent a5a5a57 commit 9608d4551d2ef9c2774c2d9574181f2c98923005
Showing with 25 additions and 2 deletions.
  1. +2 −2 addons/website_sale/models/website.py
  2. +23 −0 addons/website_sale/tests/test_website_sale_pricelist.py
@@ -68,7 +68,7 @@ def _get_pl_partner_order(self, country_code, show_visible, website_pl, current_
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 @@ def get_pricelist_available(self, show_visible=False):
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 get_request_website():
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:

1 comment on commit 9608d45

@rdeodoo

This comment has been minimized.

Copy link
Contributor Author

commented on 9608d45 Mar 18, 2019

Coming from #28301

Please sign in to comment.
You can’t perform that action at this time.