68 lines
2.9 KiB
Python
68 lines
2.9 KiB
Python
|
|
from odoo import api, fields, models, tools, SUPERUSER_ID
|
|
from odoo.osv import expression
|
|
from odoo.tools.safe_eval import safe_eval
|
|
|
|
|
|
class IrRule(models.Model):
|
|
_inherit = 'ir.rule'
|
|
|
|
backend_behaviour = fields.Selection([
|
|
("true", "Grant access"),
|
|
("false", "Deny access"),
|
|
], string='Backend behaviour',
|
|
help="""This is bypass for main rule definition.
|
|
When working from backend there is usually no 'website_id' value in the rule evaluation context
|
|
and rules that using 'website_id' evaluated as False which is not always desirable""")
|
|
|
|
@api.model
|
|
def _eval_context(self):
|
|
context = super(IrRule, self)._eval_context()
|
|
context['website_id'] = self._context.get('website_id')
|
|
return context
|
|
|
|
@api.model
|
|
@tools.ormcache_context('self._uid', 'model_name', 'mode', keys=["website_id"])
|
|
def _compute_domain(self, model_name, mode="read"):
|
|
if mode not in self._MODES:
|
|
raise ValueError('Invalid mode: %r' % (mode,))
|
|
|
|
if self._uid == SUPERUSER_ID:
|
|
return None
|
|
|
|
query = """ SELECT r.id FROM ir_rule r JOIN ir_model m ON (r.model_id=m.id)
|
|
WHERE m.model=%s AND r.active AND r.perm_{mode}
|
|
AND (r.id IN (SELECT rule_group_id FROM rule_group_rel rg
|
|
JOIN res_groups_users_rel gu ON (rg.group_id=gu.gid)
|
|
WHERE gu.uid=%s)
|
|
OR r.global)
|
|
""".format(mode=mode)
|
|
self._cr.execute(query, (model_name, self._uid))
|
|
rule_ids = [row[0] for row in self._cr.fetchall()]
|
|
if not rule_ids:
|
|
return []
|
|
|
|
# browse user and rules as SUPERUSER_ID to avoid access errors!
|
|
eval_context = self._eval_context()
|
|
user_groups = self.env.user.groups_id
|
|
global_domains = [] # list of domains
|
|
group_domains = [] # list of domains
|
|
for rule in self.browse(rule_ids).sudo():
|
|
# BEGIN redefined part of original _compute_domain of odoo/base/addons/ir/ir_rule.
|
|
# have to redefine all method to take in account new ir.rule ``backend_behaviour`` setting
|
|
dom = []
|
|
if not eval_context.get('website_id') and rule.backend_behaviour:
|
|
dom = [(1, '=', 1)] if rule.backend_behaviour == 'true' else [(0, '=', 1)]
|
|
else:
|
|
# evaluate the domain for the current user
|
|
dom = safe_eval(rule.domain_force, eval_context) if rule.domain_force else []
|
|
dom = expression.normalize_domain(dom)
|
|
# END redefined part of original _compute_domain
|
|
if not rule.groups:
|
|
global_domains.append(dom)
|
|
elif rule.groups & user_groups:
|
|
group_domains.append(dom)
|
|
|
|
# combine global domains and group domains
|
|
return expression.AND(global_domains + [expression.OR(group_domains)])
|