hockeyman
hockeyman

Reputation: 1183

Odoo fields access rights/rules

I want to make some of fields in record not editable for user who, is selected at field forbridden_user. But not all fields. Some of fields must still be editable for him. How could I achieve that?

Upvotes: 2

Views: 5671

Answers (2)

Ludwik Trammer
Ludwik Trammer

Reputation: 25032

There are two separate issues here:

  1. Making the field appear readonly in the form.
  2. Securing it so it truly can not be modified.

Those are separate issues, and by addressing only the first point you can get a very unpleasant surprise in the future.

Unfortunately Odoo doesn't comes with a per-field permissions framework (you can read my rant about this here).

If you want you can use a module I created while working on a project, that addresses this very issue.

After downloading the module and adding protected_fields to your module's dependencies you would do something like this:

class YourModel(models.Model):
    _name = 'your.model'
    _inherit = [
        'protected_fields.mixin',
    ]
    _protected_fields = ['field_you_want_to_protect']

    field_you_want_to_protect = fields.Char()
    forbridden_user = fields.Many2one('res.users')
    current_user_forbidden = fields.Boolean(compute="_compute_current_user_forbidden")

    @api.one
    @api.depends('forbridden_user')
    def _compute_current_user_forbidden(self):
        """
        Compute a field indicating whether the current user
        shouldn't be able to edit some fields.
        """
        self.current_user_forbidden = (self.forbridden_user == self.env.user)

    @api.multi
    def _is_permitted(self):
        """
        Allow only authorised users to modify protected fields
        """
        permitted = super(DetailedReport, self)._is_permitted()
        return permitted or not self.current_user_forbidden

This will take care of securely protecting the field on the server side and additionally create a current_user_forbidden field. The field will be set to True when the current user is equal to forbridden_user. We can use this on client side to make the protected field appear readonly.

Add the computed field to your view (as an invisible field - we just need its value to be available) and add the attrs attribute to the field(s) you want to protect, with a domain that will make the field appear readonly when the current_user_forbidden field is to True:

<field name="current_user_forbidden" invisible="1"/>
<field name="field_you_want_to_protect" attrs="{'readonly': [('current_user_forbidden', '=', True)]}"/>

Of course instead of field_you_want_to_protect you should use your own field you want to protect.

Upvotes: 7

shravan cherukuri
shravan cherukuri

Reputation: 490

The basic idea here is, ,
1) inherit the view
2) specify the groups to which you want to restrict the fields
3) then modify the field attributes.
I am pasting here the sample code, which will make Employee contirbution field readonly when Data Team group users logged in.

<record id="view_contribution_fields_form" model="ir.ui.view">
            <field name="name">member.contribution.form.editable.list</field>
            <field name="model">member.contribution</field>
            <field name="inherit_id" ref="contribution_view_form"/> <!-- ref = 'module_name.form_view_id'-->
            <field name="groups_id" eval="[(6, 0, [ref('group_data_team')])]"/>
            <field name="arch" type="xml">
                  <field name="contribution_employee" position="attributes">
                      <attribute name="readonly">1</attribute>
                  </field>
            </field>
         </record>

like this you can modify the field attributes when a specific user logs in.

Upvotes: 0

Related Questions