From 51fd5d3c059f583fbd86686e4e76f4619945c50b Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev <iel@odoo.com> Date: Tue, 14 Feb 2023 11:37:43 +0000 Subject: [PATCH] [FIX] website_sale_digital: let salesman download digital via portal Portal shows all Sale Orders available for current user. For example, salesman can see his sales. If such a user can download digital files via product form in backend, it makes sense to let user download them via SO page on portal. However, it wasn't the case because /my/download requires product be purchased by current user [1]. Fix it by checking read access first. STEPS * in backend create SO with digital product (customer must be different from current user) * create invoice and register a payment * navigate to portal (without using customer's token), * open SO, click download on digital product [1]: https://github.com/odoo/odoo/blob/1a24477fab4dd323cf94c010321d8942fb2c1a01/addons/website_sale_digital/models/account_invoice.py#L14-L22 opw-3144600 closes odoo/odoo#112639 Signed-off-by: Morgane Demesmaeker <edm@odoo.com> --- .../website_sale_digital/controllers/main.py | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/addons/website_sale_digital/controllers/main.py b/addons/website_sale_digital/controllers/main.py index cac2a1de0610..acbca1e70b67 100644 --- a/addons/website_sale_digital/controllers/main.py +++ b/addons/website_sale_digital/controllers/main.py @@ -8,6 +8,7 @@ import mimetypes from werkzeug.utils import redirect from odoo import http +from odoo.exceptions import AccessError from odoo.http import request from odoo.addons.sale.controllers.portal import CustomerPortal from odoo.addons.website_sale.controllers.main import WebsiteSale @@ -81,25 +82,25 @@ class WebsiteSaleDigital(CustomerPortal): else: return redirect(self.orders_page) - # Check if the user has bought the associated product - res_model = attachment['res_model'] - res_id = attachment['res_id'] - purchased_products = request.env['account.move.line'].get_digital_purchases() - - if res_model == 'product.product': - if res_id not in purchased_products: - return redirect(self.orders_page) - - # Also check for attachments in the product templates - elif res_model == 'product.template': - template_ids = request.env['product.product'].sudo().browse(purchased_products).mapped('product_tmpl_id').ids - if res_id not in template_ids: - return redirect(self.orders_page) - - else: - return redirect(self.orders_page) + try: + self.env['ir.attachment'].browse(attachment_id).check('read') + except AccessError: # The user does not have read access on the attachment. + # Check if access can be granted through their purchases. + res_model = attachment['res_model'] + res_id = attachment['res_id'] + digital_purchases = request.env['account.move.line'].get_digital_purchases() + if res_model == 'product.product': + purchased_product_ids = digital_purchases + elif res_model == 'product.template': + purchased_product_ids = request.env['product.product'].sudo().browse( + digital_purchases + ).mapped('product_tmpl_id').ids + else: + purchased_product_ids = [] # The purchases must be related to products. + if res_id not in purchased_product_ids: # No related purchase was found. + return redirect(self.orders_page) # Prevent the user from downloading. - # The client has bought the product, otherwise it would have been blocked by now + # The user has bought the product, or has the rights to the attachment if attachment["type"] == "url": if attachment["url"]: return redirect(attachment["url"]) -- GitLab