Skip to content

Commit

Permalink
[FIX] website_sale: prevent compute search to be run in sudo
Browse files Browse the repository at this point in the history
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 14, 2019
1 parent a5a5a57 commit 9608d45
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
4 changes: 2 additions & 2 deletions addons/website_sale/models/website.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -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): if not show_visible or group_pricelists.selectable or group_pricelists.id in (current_pl, order_pl):
pricelists |= group_pricelists 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 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): 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 # `property_product_pricelist` is already multi-website compliant
Expand Down Expand Up @@ -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 isocountry = request and request.session.geoip and request.session.geoip.get('country_code') or False
partner = self.env.user.partner_id partner = self.env.user.partner_id
last_order_pl = partner.last_website_so_id.pricelist_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, pricelists = website._get_pl_partner_order(isocountry, show_visible,
website.user_id.sudo().partner_id.property_product_pricelist.id, website.user_id.sudo().partner_id.property_product_pricelist.id,
request and request.session.get('website_sale_current_pl') or None, request and request.session.get('website_sale_current_pl') or None,
Expand Down
23 changes: 23 additions & 0 deletions addons/website_sale/tests/test_website_sale_pricelist.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -136,6 +136,29 @@ def get_request_website():
self.addCleanup(patcher.stop) 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): class TestWebsitePriceListMultiCompany(TransactionCase):
def setUp(self): def setUp(self):
''' Create a basic multi-company pricelist environment: ''' Create a basic multi-company pricelist environment:
Expand Down

1 comment on commit 9608d45

@rdeodoo
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming from #28301

Please sign in to comment.