diff --git a/auditlog_security/models/__init__.py b/auditlog_security/models/__init__.py
index db0c1ec6291..6a93aed1079 100644
--- a/auditlog_security/models/__init__.py
+++ b/auditlog_security/models/__init__.py
@@ -1,7 +1,7 @@
-# Copyright 2021-2024 Therp B.V.
+# Copyright 2021-2025 Therp B.V.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import auditlog_rule
from . import auditlog_line_access_rule
-from . import ir_rule
+from . import auditlog_log
from . import auditlog_log_line
diff --git a/auditlog_security/models/auditlog_line_access_rule.py b/auditlog_security/models/auditlog_line_access_rule.py
index e7651ff41d2..84013ec950f 100644
--- a/auditlog_security/models/auditlog_line_access_rule.py
+++ b/auditlog_security/models/auditlog_line_access_rule.py
@@ -1,7 +1,7 @@
# Copyright 2021-2024 Therp B.V.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo import api, fields, models
+from odoo import fields, models
class AuditlogLineAccessRule(models.Model):
@@ -23,96 +23,3 @@ class AuditlogLineAccessRule(models.Model):
"auditlog.rule", "auditlog_access_rule_ids", readonly=True, ondelete="cascade"
)
state = fields.Selection(related="auditlog_rule_id.state", readonly=True)
-
- def needs_rule(self):
- self.ensure_one()
- return bool(self.group_ids)
-
- def get_linked_rules(self):
- return self.env["ir.rule"].search(
- [("auditlog_line_access_rule_id", "in", self.ids)]
- )
-
- def unlink(self):
- to_delete = self.get_linked_rules()
- res = super(AuditlogLineAccessRule, self).unlink()
- if res:
- res = res and to_delete.unlink()
- return res
-
- def add_default_group_if_needed(self):
- self.ensure_one()
- res = False
- if not self.group_ids and self.field_ids:
- res = self.with_context(no_iter=True).write(
- {"group_ids": [(6, 0, [self.env.ref("base.group_user").id])]}
- )
- return res
-
- @api.model_create_multi
- def create(self, vals):
- res = super(AuditlogLineAccessRule, self).create(vals)
- res.add_default_group_if_needed()
- res.regenerate_rules()
- return res
-
- def write(self, vals):
- res = super(AuditlogLineAccessRule, self).write(vals)
- for this in self:
- added = this.add_default_group_if_needed()
- if (
- any(
- [
- x in vals
- for x in ("group_ids", "field_ids", "model_id", "all_fields")
- ]
- )
- or added
- ):
- this.regenerate_rules()
-
- return res
-
- def remove_rules(self):
- for this in self:
- this.get_linked_rules().unlink()
-
- def regenerate_rules(self):
- for this in self:
- this.remove_rules()
- dict_values = this._prepare_rule_values()
- for values in dict_values:
- self.env["ir.rule"].create(values)
-
- def _prepare_rule_values(self):
- self.ensure_one()
- if not self.needs_rule():
- return []
- domain_force = "[" + " ('log_id.model_id' , '=', %s)," % (self.model_id.id)
- if self.field_ids:
- domain_force = "[('field_id', 'in', %s)]" % (self.field_ids.ids)
- model = self.env.ref("auditlog.model_auditlog_log_line")
- else:
- domain_force = "[('model_id', '=', %s)]" % (self.model_id.id)
- model = self.env.ref("auditlog.model_auditlog_log")
- auditlog_security_group = self.env.ref(
- "auditlog_security.group_can_view_audit_logs"
- )
- return [
- {
- "name": "auditlog_extended_%s" % self.id,
- "model_id": model.id,
- "groups": [(6, 0, self.group_ids.ids)],
- "perm_read": True,
- "domain_force": domain_force,
- "auditlog_line_access_rule_id": self.id,
- },
- {
- "name": "auditlog_extended_%s" % self.id,
- "model_id": model.id,
- "groups": [(6, 0, [auditlog_security_group.id])],
- "perm_read": True,
- "domain_force": [(1, "=", 1)],
- "auditlog_line_access_rule_id": self.id,
- },
- ]
diff --git a/auditlog_security/models/auditlog_log.py b/auditlog_security/models/auditlog_log.py
new file mode 100644
index 00000000000..ae01442af80
--- /dev/null
+++ b/auditlog_security/models/auditlog_log.py
@@ -0,0 +1,29 @@
+# Copyright 2025 Therp B.V.
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+
+
+class AuditlogLog(models.Model):
+ _inherit = "auditlog.log"
+
+ rule_id = fields.Many2one("auditlog.rule", compute="_compute_rule_id", store=True)
+ allowed_group_ids = fields.Many2many(
+ "res.groups", compute="_compute_allowed_group_ids", store=True
+ )
+
+ @api.depends("model_id")
+ def _compute_rule_id(self):
+ for log in self:
+ log.rule_id = self.env["auditlog.rule"].search(
+ [("model_id", "=", log.model_id.id)]
+ )
+
+ @api.depends("rule_id")
+ def _compute_allowed_group_ids(self):
+ for log in self:
+ log.allowed_group_ids = (
+ self.env["auditlog.line.access.rule"]
+ .search([("auditlog_rule_id", "=", log.rule_id.id)])
+ .group_ids
+ )
diff --git a/auditlog_security/models/auditlog_log_line.py b/auditlog_security/models/auditlog_log_line.py
index 5738b58d0a0..244838e60f5 100644
--- a/auditlog_security/models/auditlog_log_line.py
+++ b/auditlog_security/models/auditlog_log_line.py
@@ -20,6 +20,9 @@ class AuditlogLogLine(models.Model):
"ir.model", compute="_compute_model_id", store=True, index=True
)
res_id = fields.Integer(compute="_compute_res_id", store=True, index=True)
+ allowed_group_ids = fields.Many2many(
+ "res.groups", compute="_compute_allowed_group_ids", store=True
+ )
@api.depends("log_id.method")
def _compute_method(self):
@@ -40,3 +43,25 @@ def _compute_model_id(self):
def _compute_res_id(self):
for this in self:
this.res_id = this.log_id.res_id
+
+ @api.depends(
+ "field_id",
+ "log_id.rule_id",
+ "log_id.rule_id.auditlog_line_access_rule_ids.group_ids",
+ "log_id.rule_id.auditlog_line_access_rule_ids.field_ids",
+ )
+ def _compute_allowed_group_ids(self):
+ for line in self:
+ # Do not give a value to sql model
+ if line._name == "auditlog.log.line.view":
+ continue
+ line.allowed_group_ids = (
+ self.env["auditlog.line.access.rule"]
+ .search(
+ [
+ ("auditlog_rule_id", "=", line.log_id.rule_id.id),
+ ("field_ids", "in", line.field_id.ids),
+ ]
+ )
+ .group_ids
+ )
diff --git a/auditlog_security/models/auditlog_rule.py b/auditlog_security/models/auditlog_rule.py
index eceba51f42e..79d322903ba 100644
--- a/auditlog_security/models/auditlog_rule.py
+++ b/auditlog_security/models/auditlog_rule.py
@@ -118,10 +118,7 @@ def subscribe(self):
for rule in self:
server_action = rule._create_server_action()
server_action.create_action()
- res = super(AuditlogRule, self).subscribe()
- for rule in self:
- rule.auditlog_line_access_rule_ids.regenerate_rules()
- # rule now will have "View Log" Action, make that visible only for admin
+ res = super().subscribe()
if res:
self.action_id.write(
{"groups_id": [(6, 0, [self.env.ref("base.group_system").id])]}
@@ -129,8 +126,6 @@ def subscribe(self):
return res
def unsubscribe(self):
- for rule in self:
- rule.auditlog_line_access_rule_ids.remove_rules()
for rule in self:
rule.server_action_id.unlink()
- return super(AuditlogRule, self).unsubscribe()
+ return super().unsubscribe()
diff --git a/auditlog_security/models/ir_rule.py b/auditlog_security/models/ir_rule.py
deleted file mode 100644
index 8def6cc7115..00000000000
--- a/auditlog_security/models/ir_rule.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2021-2024 Therp B.V.
-# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-
-from odoo import fields, models
-
-
-class IrRule(models.Model):
- _inherit = "ir.rule"
-
- auditlog_line_access_rule_id = fields.Many2one(
- "auditlog.line.access.rule",
- required=False,
- index=True,
- ondelete="cascade",
- help="Auditlog line access Rule that generated this ir.rule",
- )
diff --git a/auditlog_security/security/ir_rule.xml b/auditlog_security/security/ir_rule.xml
index dfea064c1c5..d247e7ab499 100644
--- a/auditlog_security/security/ir_rule.xml
+++ b/auditlog_security/security/ir_rule.xml
@@ -15,4 +15,22 @@
+
+ Access to auditlog.log
+
+ [('allowed_group_ids', 'in', user.groups_id.ids)]
+
+
+
+
+ Access to auditlog.log.line
+
+ [('allowed_group_ids', 'in', user.groups_id.ids)]
+
+
+