odoo

Security in Odoo Application: Best Practices for Safe Business Operations

Odoo is a popular open-source ERP (Enterprise Resource Planning) software suite that encompasses various business applications, including CRM, sales, inventory management, accounting, and more. Security is a crucial aspect of any software application, and Odoo provides several features to manage security effectively.

In a business application such as Odoo, one of the first questions to consider is who can access the data.When the data is related to security, it is located in the security folder. so , we make security directory inside the module and inside it we define .csv and .xml file to maintain security in our odoo application.

Basically there are  two ways , we can handle security in odoo appliaction.

1.Access right : control over CRUD operation (can be define xml or csv file)

2.Record rules : (define record level access right)

let's learn both of them in more details

1. Access right

Access rights in Odoo define what actions users can perform on different records within the system. These rights are managed through Access Control Lists (ACLs), which specify the permissions granted to users based on their roles or groups. Access rights play a crucial role in controlling the security and privacy of data within an Odoo instance.

it basically control over the CRUD operations. it can be define in xml or the csv file as well.

When no access rights are defined on a model, Odoo determines that no users can access the data. It is even notified in the log:

Access rights are defined as records of the model ir.model.access. Each access right is associated with a model, a group (or no group for global access) and a set of permissions: create, read, write and unlink . Such access rights are usually defined in a CSV file named ir.model.access.csv.

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_todo_category,access.todo.category,model_todo_category,base.group_user,1,0,0,0

access_school_admin,access.school.admin,model_school,school.admin_permission,1,1,1,1
access_school_teacher,access.school.teacher,model_school,school.teacher_permission,1,1,1,0
access_school_student,access.school.student,model_school,school.student_permission,1,0,0,0
  • id is an .
  • name is the name of the ir.model.access.
  • model_id:id refers to the model which the access right applies to. The standard way to refer to the model is model_<model_name>, where <model_name> is the _name of the model with the . replaced by _. Seems cumbersome? Indeed it is…  example model_school_student
  • group_id:id refers to the group which the access right applies to.
  • perm_read,perm_write,perm_create,perm_unlink: read, write, create and unlink permissions.

so Access rights of all the models must be provided . we can override it according to the requirements.

we can also defile access right of the models in .xml file as well. you can see the below code snippet to get more information

<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="school_admin_all_permission" model="ir.model.access">
    <field name="name">school admin</field>
    <field name="model_id" ref="model_name_of_the_model_separate_by_underscore"/>
    <field name="group_id" ref="base.group_user"/>
    <field name="perm_read">1</field>
    <field name="perm_create">1</field>
    <field name="perm_write">1</field>
    <field name="perm_unlink">1</field>
</record>
</odoo>

 

2.Record Rules

In addition to global access rights, Odoo also supports record-level access control. This allows you to define access rights on individual records based on certain conditions or criteria.

Record rules in Odoo provide a mechanism to apply access restrictions to specific records based on certain conditions. These rules allow you to control which records users can read, write, create, or delete, based on predefined criteria. Record rules are a powerful feature that helps you enforce fine-grained access control within your Odoo instance.

Example: You can set up a record rule to restrict access to confidential contracts only to users belonging to the legal department.

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data noupdate="1">
        <record id="suitable_and_unique_id_name" model="ir.rule">
            <field name="name">Create/Read - Assignment</field>
            <field name="perm_read" eval="1" />
            <field name="perm_create" eval="1" />
            <field name="perm_write" eval="0" />
            <field name="perm_unlink" eval="0" />
            <field ref="module_name.model_model_name_by_underscore" name="model_id"/>
            <!-- <field name="domain_force">[(1,'=',1)]</field> -->
            <!-- <field name="domain_force">[('create_uid','=',user.id)]</field> -->
            <!-- <field name="domain_force">[('user_id','=',user.id)]</field> -->
            <field name="domain_force">[('status', '=', 'approved')]</field>
            <!-- <field name="groups" eval="[(4, ref('module_name.group_name'))]"/> -->
            <field name="groups" eval="[(6, 0, [ref('module_name.group_name')])]"/>
        </record>

    </data>
</odoo>

 

 

In general in odoo we define groups or role to maintain security. we create group, assign record rules or access right on particular group. we can also assign group on field,view,menu,actions and so on to maintain security in odoo application.

There are basically two types of groups in odoo

1.individual

In individual group , if particular user want to add on that group you simply add user on particular group or if you won't you simple remove user from the group by untick particular group from the user profile.

example:

2.multilevel

you can select one from multiple value in this types of group.

example:

 

 

Security groups in odoo

You can create security group as below

    <record id="group_user" model="res.groups">
      <field name="name">User Access</field>
    </record>

 You can create security category as below

    <record model="ir.module.category" id="employee_category">
      <field name="name">Employee</field>
    </record>

 

You can assign group on particular category as below:

    <record id="group_user" model="res.groups">
      <field name="name">User Access</field>
      <field name="category_id" ref="school.employee_category"/>
    </record>

Now overall code for creating category,group and maintain hireracy is below:

<?xml version="1.0" encoding="utf-8"?>
<odoo>
  <data>

    <!-- for header  -->
    <record model="ir.module.category" id="employee_parent_category">
      <field name="name">Employee</field>
    </record>
    <record model="ir.module.category" id="employee_user_access">
      <field name="name">Employee User Access</field>
      <field name='parent_id' ref="assignment.employee_parent_category"/>
      <field name="description">User access level for this module</field>
      <field name="sequence">3</field>
    </record>

    <record id="group_user" model="res.groups">
      <field name="name">User Access</field>
      <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
      <field name="users" eval="[(4, ref('base.user_root'))]"/>
      <!-- for takes user_root template as default for user in this group  -->
      <field name="category_id" ref="assignment.employee_user_access"/>
    </record>

    <record id="group_hr" model="res.groups">
      <field name="name">HR Access</field>
      <field name="implied_ids" eval="[(4, ref('assignment.group_user'))]"/>
      <field name="category_id" ref="assignment.employee_user_access"/>
    </record>


    <record id="group_admin" model="res.groups">
      <field name="name">Admin</field>
      <field name="implied_ids" eval="[(4, ref('assignment.group_hr'))]"/>
      <field name="category_id" ref="assignment.employee_user_access"/>
    </record>

  </data>
</odoo>

Apply odoo security groups in views,fileds level,window actions and many more as 

<field name='company' groups='module_name.id_of_your_group,your_nxt_group_id'/>
<filter

string="Birth Date"
domain=[]
context="{'group_by':'birth_date'}"
groups='module_name.id_of_your_group,your_nxt_group_id'

/>

<!-- if you want ot implement in window actions -->
<field name='groups_id' eval="[4,0,ref('groups='module_name.id_of_your_group,your_nxt_group_id'')]"/>

<!-- in python level
company=fields.Char(string="company",groups='module_name.id_of_your_group,your_nxt_group_id') -->

 

How to overide/reuse security group category

you simply write the categorry_id where you wan to overide 

you can see that on  addons>base>data>ir_module_category_data, from here you can used id of particular category to include group inside particular category

 

    <record id="group_hr" model="res.groups">
      <field name="name">HR Access</field>
      <field name="implied_ids" eval="[(4, ref('assignment.group_user'))]"/>
      <field name="category_id" ref="base.module_category_hidden"/>
    </record>

 

How to extend/inherit groups in odoo | implied_ids groups

<record id="group_hr" model="res.groups">
    <field name="name">HR Access</field>
    <field name="category_id" ref="base.module_category_hidden"/>
    <field name="implied_ids" eval="[(6,0,[ref('assignment.group_user')
                                            ref(assignmant.group_admin),
                                            ref(assignmant.group_teacher),  
                                    ])]"/>
</record>

<!-- inherit all this group using implied_ids  -->

 

 

 

 

more about security 

there are some groups that  odoo has already created among them some are as follows:

1.base.group_system

  • Name: Settings
  • Purpose: Grants access to configuration and technical settings.  belongs to the Settings group.(whos has setting menu access i.e Administration)

2.base.group_user

  • Name: User
  • Purpose: Basic access to Odoo functionalities. need to login to system

3.base.group_public

  • Name: Public
  • Purpose: For public users with no login required (portal access or website visitors).

4.base.group_portal

  • Name: Portal
  • Purpose: Limited access via the Odoo portal, typically for customers or external partners.

5.base.group_no_one

  • Name: No One
  • Purpose: No access rights, used to restrict access completely.

6.base.group_erp_manager

  • Name: Administrator
  • Purpose: Comprehensive administrative rights, including permissions from the base.group_system.

 

Administration: Settings

When you select Settings from the Administration dropdown, the user is assigned to the base.group_system group.

  • Group: base.group_system
  • Name: Settings
  • Purpose: This group provides access to configuration and technical settings in Odoo. Users in this group can manage modules, configure settings, and access more advanced options within the system.

Administration: Access Rights

When you select Access Rights from the Administration dropdown, the user is assigned to the base.group_erp_manager group.

  • Group: base.group_erp_manager
  • Name: Administrator
  • Purpose: This group provides comprehensive administrative rights, including all the permissions from the base.group_system group and additional administrative privileges across various modules. Users in this group have the highest level of access and control over the Odoo environment.

 

  • Settings (base.group_system): Provides access to system configuration and technical settings. Suitable for users who need to manage system settings but not necessarily perform all administrative tasks.
  • Access Rights (base.group_erp_manager): Provides full administrative access, including permissions to manage users, access all settings, and perform any administrative task in the system.

By selecting the appropriate option from the Administration dropdown, you can control the level of access and permissions that a user has in the Odoo system.

 

 

Assign user to particular groups

 

from odoo import models, api

class ResUsers(models.Model):
    _inherit = 'res.users'

    @api.model
    def assign_to_erp_manager(self, user_id):
        user = self.browse(user_id)
        erp_manager_group = self.env.ref('base.group_erp_manager')
        if erp_manager_group not in user.groups_id:
            user.groups_id += erp_manager_group
        return True


    def is_system_user(self):
        # Check if the user belongs to the 'base.group_system' group
        group_system = self.env.ref('base.group_system')
        return self.has_group('base.group_system')

 you can assign user to group through xml as well

\

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <record id="user_admin_group_assignment" model="res.users">
        <field name="name">Administrator User</field>
        <field name="login">admin</field>
        <field name="groups_id" eval="[(4, ref('base.group_erp_manager'))]"/>
    </record>
</odoo>

 


About author

author image

Amrit panta

Fullstack developer, content creator



Scroll to Top