Odoo Record Rules

Record Rules are an important part of security in Odoo.  They control which records users can access.  For example, sales users can only access their own quotations and sales orders (see below).

  • Record Rules can make it easier to develop functionality in Odoo (because the rules have already been setup)
  • However, they can cause problems if there are multiple requirements related to one Model (database table).
    • So it is possible that installing another app or module (or just enabling another feature, such as Private Addresses) can have unexpected results.

Quick Guide

  1. Users are members of application access groups (e.g. Peter Lee might be a Purchase Manager and an Inventory User).
  2. Each of those access groups may “inherit” access from a related group, for example
    • Purchase Manager inherits the Purchase User rights
    • Purchase User inherits the Internal User rights
  3. Users will also be members of ‘technical’ access groups, each of which has a specific purpose, for example:
    • Manage multiple units of measure
    • Analytic accounting
  4. Each of the access groups (both types) will grant access to:
    1. Database
      1. Models
      2. Records (through Record Rules)
      3. Fields (not normally used) 
    2. Views 
    3. Menus
    4. Windows Actions
    5. Other elements (Buttons, Filters, Wizards)
  5. Access from all these groups is combined, so a user could have Read access from one group and Write access from another group (see Permissions below).
  6. If there are no Record Rules, there are no record-level restrictions.
  7. In Odoo version 11 and earlier, the Administrator account was not subject to Record Rules.  In Odoo 12 and later, the Administrator account is a member of all Access Groups and subject to Record Rules, but it is also possible to become a “Superuser” and bypass access rules. 

Record Rules

Record Rules make use of domain to specify which records can be selected.

There are two types of Record Rule:

  1. Global rules (with no access group specified).
    • These restrict access, and cannot be bypassed by other Record Rules.
    • They are generally used for multi-company restrictions.
    • They are quite easy to understand!
  2. Group-specific rules (for one or more access groups – e.g. Purchase Manager)
    • These grant permission (subject to the restrictions imposed by the Global Rules).
    • If there are multiple Group-specific rules then access is granted if ANY of the conditions are satisfied.
      • This can make Group-specific rules more difficult to understand, and care needs to be taken when using them.

Example

The access group “Sales / User: Own Documents Only” has a Record Rule on Sales Orders (and Quotations) with this domain:

['|',
   ('user_id','=',user.id),
   ('user_id','=',False)
] 

This will only allow access to:

  • the user’s own orders / quotations (where salesman = current user)
  • orders with no salesman (user_id) specified).

Alongside this, the group “Sales / User: All Documents” has a Record Rule with this domain:

 [(1,'=',1)] 

This will grant access to ALL Sales Orders / Quotations.

Note: there are identical Record Rules for Leads (the field names are the same).

Group Record Rules are almost always in sets of two, one to restrict access, one to grant full access (a set of three or more rules is also possible).

Permissions

Record Rules grant permission for one or all of the following actions:

  1. Read
  2. Write (update)
  3. Create
  4. Delete

Note that Read access is required in order to have any access!

There are several possible types of access, including:

  • Read-Only
  • Read and Write (but not create and delete)
  • Read, Write and Create but not delete
  • Full access

This can be done either through Model access or Record Rules, and there is an important difference between the two:

  1. If Read Access is not specified for a Model and user group, the user(s) will not have Read Access to that Model*
  2. If Read Access is not specified for a Record Rule (for a user group), the domain in that Rule will not apply, and so will not restrict user access*.
    • However, if there are other Record Rules for Read access they would apply.

* Note that in both the above examples, users may be members of other user groups that will either grant or restrict access.

Using Sales Order and Quotations (sale.order) as an example:

  • As standard, only the Sales Manager can delete Sales Orders (this is from the Model Access)
  • As explained above, some sales users can only access their own orders (through Record Rules)
  • You could add record rules so that:
    1. Only supervisors or managers can cancel confirmed Sales Orders
    2. All sales users can cancel Quotations (draft Sales Orders)
      • A cancelled Sales Order is still in the Odoo database, and a manager would be able to delete it.

Challenges

It’s easy to have problems with Record Rules because of the way they interact with each other. These can be in either direction:

  • access is allowed when it should not be,
  • users are not allowed do something they should be able to do

Here’s one example:

Private addresses

Odoo 12 introduced a Record Rule that was designed to limit access to “private addresses”. It’s on the Contacts model (res.partner).

Just like the above example, there are a pair of Record Rules:

1.  Allow access to “private addresses” for selected users

[('type', '=', 'private')]

2. Allow access for all users to other “non-private addresses”

['|', 
('type', '!=', 'private'),
('type', '=', False)
]

This Record Rule grants access to all internal users through the “Internal User” access group (“Employee” in earlier versions). This group is inherited by all application access groups.

The problem is that the second Record Rule would effectively override other Record Rules for Contacts.

  • For example, you might have used Record Rules to limit access to vendors (suppliers), but:
    • a user who had not had access to vendors would now be granted access (because type will be blank).
      • They would also be able to access private addresses for customers and other types of contact!

That’s because access is granted if the conditions for ANY of the Group-specific rules are satisfied – and these can come from multiple access groups.

The solution is either to remove the two “private address” rules or to replace them with several rules that cover all the combinations.

Alternatives

It is also possible to restrict access without using Record Rules.

The disadvantage of these methods is that it will normally require the restrictions to be applied in multiple places (which, of course, is what makes it more flexible). But it is easy to miss one or more views and then the user has access they should not have!

List of Record Rules for a user (Odoo 13)

Navigate to Settings / Users & Companies / Users

These “smart buttons” can be useful for troubleshooting, and you can use Filters to show information for one or more Models:

This shows us that the user has full access to their own sales order lines (from the “Sales / User: Own Documents Only” group) plus Read-Only access to Sales Order lines for projects (as the “Project Administrator”).

This is the domain for the second Record Rule:

['&', '&',
     ('state', 'in', ['sale', 'done']),
     ('is_service', '=', True),
    '|', ('project_id','!=', False), ('task_id','!=', False)]

This selects Sales Order Lines that are:

  • confirmed or locked, and
  • service items and
  • with either a project or task id

This will be used when billing from timesheets, so it logical that this access is available for a Project Administrator.

Note: there should be no conflict between these two Record Rules (sometimes the combination produces undesirable results, as explained above).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s