Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Available addons
addon | version | maintainers | summary
--- | --- | --- | ---
[attachment_unindex_content](attachment_unindex_content/) | 19.0.1.0.0 | <a href='https://github.com/moylop260'><img src='https://github.com/moylop260.png' width='32' height='32' style='border-radius:50%;' alt='moylop260'/></a> <a href='https://github.com/ebirbe'><img src='https://github.com/ebirbe.png' width='32' height='32' style='border-radius:50%;' alt='ebirbe'/></a> <a href='https://github.com/luisg123v'><img src='https://github.com/luisg123v.png' width='32' height='32' style='border-radius:50%;' alt='luisg123v'/></a> | Disable indexing of attachments
[auditlog](auditlog/) | 19.0.2.0.0 | | Audit Log
[auditlog](auditlog/) | 19.0.2.0.1 | | Audit Log
[auto_backup](auto_backup/) | 19.0.1.0.1 | | Backups database
[base_cron_exclusion](base_cron_exclusion/) | 19.0.1.0.0 | <a href='https://github.com/LoisRForgeFlow'><img src='https://github.com/LoisRForgeFlow.png' width='32' height='32' style='border-radius:50%;' alt='LoisRForgeFlow'/></a> | Allow you to select scheduled actions that should not run simultaneously.
[base_exception](base_exception/) | 19.0.1.0.0 | <a href='https://github.com/hparfr'><img src='https://github.com/hparfr.png' width='32' height='32' style='border-radius:50%;' alt='hparfr'/></a> <a href='https://github.com/sebastienbeau'><img src='https://github.com/sebastienbeau.png' width='32' height='32' style='border-radius:50%;' alt='sebastienbeau'/></a> | This module provide an abstract model to manage customizable exceptions to be applied on different models (sale order, invoice, ...)
Expand Down
2 changes: 1 addition & 1 deletion auditlog/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Audit Log
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:3db0314c73f17e5c63ecb5205a4d29beff97812aca664e1dd624646702f14bee
!! source digest: sha256:620a80526b6f2d225f81287c03ac63b2c4b5f56fe19e2b833b6f2d31b015c093
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion auditlog/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{
"name": "Audit Log",
"version": "19.0.2.0.0",
"version": "19.0.2.0.1",
"author": "ABF OSIELL, Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/server-tools",
Expand Down
14 changes: 6 additions & 8 deletions auditlog/models/auditlog_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def _register_hook(self):

def _patch_method(self, model, method_name, check_attr):
result = new_method = False
model_class = type(model)
model_class = model.env.registry[model._name]
if method_name == "create":
new_method = self._make_create()
elif method_name == "read":
Expand All @@ -257,7 +257,7 @@ def _patch_method(self, model, method_name, check_attr):
if new_method:
new_method.origin = getattr(model_class, method_name)
setattr(model_class, method_name, new_method)
setattr(type(model), check_attr, True)
setattr(model_class, check_attr, True)
result = True
return result

Expand Down Expand Up @@ -300,15 +300,13 @@ def _revert_methods(self):
"""Restore original ORM methods of models defined in rules."""
updated = False
for rule in self:
model_model = self.env[rule.model_id.model or rule.model_model]
model_class = self.env.registry[rule.model_id.model or rule.model_model]
for method in ["create", "read", "write", "unlink", "export_data"]:
if getattr(rule, f"log_{method}") and hasattr(
getattr(model_model, method), "origin"
getattr(model_class, method), "origin"
):
setattr(
type(model_model), method, getattr(model_model, method).origin
)
delattr(type(model_model), f"auditlog_ruled_{method}")
delattr(model_class, method)
delattr(model_class, f"auditlog_ruled_{method}")
updated = True
if updated:
self._update_registry()
Expand Down
4 changes: 2 additions & 2 deletions auditlog/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Audit Log</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -372,7 +372,7 @@ <h1>Audit Log</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:3db0314c73f17e5c63ecb5205a4d29beff97812aca664e1dd624646702f14bee
!! source digest: sha256:620a80526b6f2d225f81287c03ac63b2c4b5f56fe19e2b833b6f2d31b015c093
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-tools/tree/19.0/auditlog"><img alt="OCA/server-tools" src="https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-tools-19-0/server-tools-19-0-auditlog"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/server-tools&amp;target_branch=19.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows the administrator to log user operations performed on
Expand Down
34 changes: 16 additions & 18 deletions auditlog/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,28 @@


class AuditLogRuleCommon(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.models = set()
"""Rules must be subscribed in `setUp` or in the test itself, not in
`setUpClass`: patched methods are reverted after each test."""

@classmethod
def create_rule(cls, vals):
rule = cls.env["auditlog.rule"].with_context(tracking_disable=True).create(vals)
# Keep track of patched models
cls.models |= set(rule.model_id.mapped("model"))
return rule
return cls.env["auditlog.rule"].with_context(tracking_disable=True).create(vals)

@classmethod
def tearDownClass(cls):
for rule in cls.env["auditlog.rule"].search([]):
def setUp(self):
super().setUp()
# A cleanup also runs when setUp fails after subscribing a rule,
# unlike tearDown.
self.addCleanup(self._unsubscribe_rules)

def _unsubscribe_rules(self):
for rule in self.env["auditlog.rule"].search([]):
try:
rule.set_to_draft()
except KeyError: # pragma: no cover
continue # Model not loaded yet

continue # Preexisting rule for model not loaded yet
# Assert no patched methods remain
for model in cls.models:
for method in ["create", "read", "write", "unlink"]:
assert not hasattr(getattr(cls.env[model], method), "origin"), (
f"{model} {method} still patched"
for model_class in self.env.registry.values():
for method in ["create", "read", "write", "unlink", "export_data"]:
assert not hasattr(model_class, f"auditlog_ruled_{method}"), (
f"{model_class._name} {method} still patched"
)
super().tearDownClass()
48 changes: 30 additions & 18 deletions auditlog/tests/test_auditlog.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.fields import Command
from odoo.tools import mute_logger

from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG

Expand Down Expand Up @@ -401,13 +402,15 @@ def setUpClass(cls):
}
)

cls.auditlog_rule.set_to_confirmed()
def setUp(self):
super().setUp()
self.auditlog_rule.set_to_confirmed()
# Trigger log creation
rec = cls.env["x_test.model"].create({"x_test_field": "test value"})
rec = self.env["x_test.model"].create({"x_test_field": "test value"})
rec.write({"x_test_field": "test value 2"})

cls.logs = cls.env["auditlog.log"].search(
[("res_id", "=", rec.id), ("model_id", "=", cls.test_model.id)]
self.logs = self.env["auditlog.log"].search(
[("res_id", "=", rec.id), ("model_id", "=", self.test_model.id)]
)

def assert_values(self):
Expand All @@ -431,13 +434,15 @@ def test_01_field_and_model_removal(self):
self.assert_values()

# Remove the field
self.test_field.with_context(**{MODULE_UNINSTALL_FLAG: True}).unlink()
with mute_logger("odoo.api"): # Mute 'Too many iterations for flushing fields'
self.test_field.with_context(**{MODULE_UNINSTALL_FLAG: True}).unlink()
self.assert_values()
# The field should not be linked
self.assertFalse(self.logs.mapped("line_ids.field_id"))

# Remove the model
self.test_model.with_context(**{MODULE_UNINSTALL_FLAG: True}).unlink()
with mute_logger("odoo.api"): # Mute 'Too many iterations for flushing fields'
self.test_model.with_context(**{MODULE_UNINSTALL_FLAG: True}).unlink()
self.assert_values()

# The model should not be linked
Expand Down Expand Up @@ -533,14 +538,16 @@ def setUpClass(cls):
# Updating users_to_exclude_ids
cls.auditlog_rule.users_to_exclude_ids = [[4, cls.users_to_exclude_ids]]

# Subscribe auditlog.rule
cls.auditlog_rule.set_to_confirmed()

cls.auditlog_log = cls.env["auditlog.log"]

def setUp(self):
super().setUp()
# Subscribe auditlog.rule
self.auditlog_rule.set_to_confirmed()

# Creating new res.partner
cls.testpartner1 = (
cls.env["res.partner"]
self.testpartner1 = (
self.env["res.partner"]
.with_context(tracking_disable=True)
.create(
{
Expand All @@ -551,10 +558,10 @@ def setUpClass(cls):
)

# Creating new res.partner from excluded user
cls.testpartner2 = (
cls.env["res.partner"]
self.testpartner2 = (
self.env["res.partner"]
.with_context(tracking_disable=True)
.with_user(cls.user.id)
.with_user(self.user.id)
.create(
{
"name": "testpartner2",
Expand Down Expand Up @@ -690,8 +697,11 @@ def setUpClass(cls):
cls.group = cls.env.ref("auditlog.group_auditlog_manager")

cls.auditlog_log = cls.env["auditlog.log"]

def setUp(self):
super().setUp()
# Subscribe auditlog.rule
cls.auditlog_rule.set_to_confirmed()
self.auditlog_rule.set_to_confirmed()

def test_01_AuditlogFull_field_group_write_log(self):
"""Change group and check successfully created log"""
Expand Down Expand Up @@ -741,9 +751,6 @@ def setUpClass(cls):
# Updating phone in fields_to_exclude_ids
cls.auditlog_rule.fields_to_exclude_ids = [[4, cls.fields_to_exclude_ids]]

# Subscribe auditlog.rule
cls.auditlog_rule.set_to_confirmed()

cls.auditlog_log = cls.env["auditlog.log"]

# Creating new res.partner
Expand All @@ -758,6 +765,11 @@ def setUpClass(cls):
)
)

def setUp(self):
super().setUp()
# Subscribe auditlog.rule
self.auditlog_rule.set_to_confirmed()

def test_01_AuditlogFast_field_exclude_write_log(self):
# Checking fields_to_exclude_ids
self.testpartner1.with_context(tracking_disable=True).write(
Expand Down
Loading