[FIX] account: prevent reading fake binary fields over rpc
Since Odoo 16 [1] account module uses some non-storable computed Binary fields
to compute and access structured data. Those data is not transformed into binary
data and is not supposed to be used outside of server environment. There are
still use cases when ORM tries to process such fields as normal Binary fields.
For example, on using export wizard [2].
This commit fixes similar problem on reading `account.move{.line}` records via
rpc.
STEPS: create `account.move` record and read it via an RPC call [3]
```
account_move_id = 666
models.execute_kw(db, uid, password, 'account.move', 'read', [account_move_id])
```
SOLUTION
1. Add missing `exportable=False` to the fake Binary fields
2. Block access to such fields via method `check_field_access_rights`
[1]:
https://github.com/odoo/odoo/commit/d8d47f9ff8554f4b39487fd2f13c153c7d6f958d
[2]: https://github.com/odoo/odoo/commit/c925ecb2a22750524020f0d111888fd76eedb0cb
[3]: https://www.odoo.com/documentation/16.0/developer/api/external_api.html
opw-3099975
closes odoo/odoo#134164
X-original-commit: 5193d145b96e34ef1e754b8421cccd8c9dab99e7
Signed-off-by: William André (wan) <wan@odoo.com>
This commit is contained in:
committed by
william-andre
parent
38d0124a93
commit
602b3f3d39
@@ -292,7 +292,7 @@ class AccountMove(models.Model):
|
||||
compute='_compute_invoice_payment_term_id', store=True, readonly=False, precompute=True,
|
||||
check_company=True,
|
||||
)
|
||||
needed_terms = fields.Binary(compute='_compute_needed_terms')
|
||||
needed_terms = fields.Binary(compute='_compute_needed_terms', exportable=False)
|
||||
needed_terms_dirty = fields.Boolean(compute='_compute_needed_terms')
|
||||
tax_calculation_rounding_method = fields.Selection(
|
||||
related='company_id.tax_calculation_rounding_method',
|
||||
@@ -488,7 +488,7 @@ class AccountMove(models.Model):
|
||||
help='Use this field to encode the total amount of the invoice.\n'
|
||||
'Odoo will automatically create one invoice line with default values to match it.',
|
||||
)
|
||||
quick_encoding_vals = fields.Binary(compute='_compute_quick_encoding_vals')
|
||||
quick_encoding_vals = fields.Binary(compute='_compute_quick_encoding_vals', exportable=False)
|
||||
|
||||
# === Misc Information === #
|
||||
narration = fields.Html(
|
||||
@@ -580,7 +580,7 @@ class AccountMove(models.Model):
|
||||
need_cancel_request = fields.Boolean(compute='_compute_need_cancel_request')
|
||||
|
||||
# used to display the various dates and amount dues on the invoice's PDF
|
||||
payment_term_details = fields.Binary(compute="_compute_payment_term_details")
|
||||
payment_term_details = fields.Binary(compute="_compute_payment_term_details", exportable=False)
|
||||
show_payment_term_details = fields.Boolean(compute="_compute_show_payment_term_details")
|
||||
show_discount_details = fields.Boolean(compute="_compute_show_payment_term_details")
|
||||
|
||||
@@ -2340,6 +2340,13 @@ class AccountMove(models.Model):
|
||||
# LOW-LEVEL METHODS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def check_field_access_rights(self, operation, field_names):
|
||||
result = super().check_field_access_rights(operation, field_names)
|
||||
if not field_names:
|
||||
weirdos = ['needed_terms', 'quick_encoding_vals', 'payment_term_details']
|
||||
result = [fname for fname in result if fname not in weirdos]
|
||||
return result
|
||||
|
||||
def copy_data(self, default=None):
|
||||
data_list = super().copy_data(default)
|
||||
for move, data in zip(self, data_list):
|
||||
|
||||
@@ -354,12 +354,12 @@ class AccountMoveLine(models.Model):
|
||||
related='company_id.tax_calculation_rounding_method',
|
||||
string='Tax calculation rounding method', readonly=True)
|
||||
# === Invoice sync fields === #
|
||||
term_key = fields.Binary(compute='_compute_term_key')
|
||||
tax_key = fields.Binary(compute='_compute_tax_key')
|
||||
compute_all_tax = fields.Binary(compute='_compute_all_tax')
|
||||
term_key = fields.Binary(compute='_compute_term_key', exportable=False)
|
||||
tax_key = fields.Binary(compute='_compute_tax_key', exportable=False)
|
||||
compute_all_tax = fields.Binary(compute='_compute_all_tax', exportable=False)
|
||||
compute_all_tax_dirty = fields.Boolean(compute='_compute_all_tax')
|
||||
epd_key = fields.Binary(compute='_compute_epd_key')
|
||||
epd_needed = fields.Binary(compute='_compute_epd_needed')
|
||||
epd_key = fields.Binary(compute='_compute_epd_key', exportable=False)
|
||||
epd_needed = fields.Binary(compute='_compute_epd_needed', exportable=False)
|
||||
epd_dirty = fields.Boolean(compute='_compute_epd_needed')
|
||||
|
||||
# === Analytic fields === #
|
||||
@@ -1262,6 +1262,13 @@ class AccountMoveLine(models.Model):
|
||||
# -------------------------------------------------------------------------
|
||||
# CRUD/ORM
|
||||
# -------------------------------------------------------------------------
|
||||
def check_field_access_rights(self, operation, field_names):
|
||||
result = super().check_field_access_rights(operation, field_names)
|
||||
if not fields:
|
||||
weirdos = ['term_key', 'tax_key', 'compute_all_tax', 'epd_key', 'epd_needed']
|
||||
result = [fname for fname in result if fname not in weirdos]
|
||||
return result
|
||||
|
||||
def invalidate_model(self, fnames=None, flush=True):
|
||||
# Invalidate cache of related moves
|
||||
if fnames is None or 'move_id' in fnames:
|
||||
|
||||
Reference in New Issue
Block a user