Search code examples
odooodoo-12

Set field to readonly if currently edited user has higher privelage


So my goal is to have group of users that are able to add new users but they should not have other admin privelages.

The way I want to solve it is by having group with permissions to only add users and another group with all the admin right. For this to be scure I need to prevent users in the first group from editing users in the second group.

I have module with this code:

<record model="ir.ui.view" id="view_user_readonly" >
    <field name="name">res.users.form.readonly</field>
    <field name="model">res.users</field>
    <field name="inherit_id" ref="base.view_users_form"/>
    <field name="arch" type="xml">
        <xpath expr="//field[@name='login']" position="attributes">
            <attribute name="readonly">True</attribute>
        </xpath>
    </field>
</record>

And it sets field to readonly for all the users. Now I would like to change is so that it is readonly when user we are trying to edit has the group base.group_system and we don't.

I tried adding code based on anwsers from the internet like this:

<record model="ir.ui.view" id="view_user_readonly" >
    <field name="name">res.users.form.readonly</field>
    <field name="model">res.users</field>
    <field name="inherit_id" ref="base.view_users_form"/>
    <field name="arch" type="xml">
        <xpath expr="//field[@name='login']" position="attributes">
            <attribute name="readonly">True</attribute>
        </xpath>
    </field>
</record>

<record model="ir.ui.view" id="view_user_readonly_settings">
    <field name="name">res.users.form.readonly.settings</field>
    <field name="model">res.users</field>
    <field name="inherit_id" ref="custom_user_fields.view_user_readonly" />
    <field name="groups_id" eval="[(6, 0, [ref('base.group_system')])]"/>
    <field name="arch" type="xml">
        <xpath expr="//field[@name='login']" position="attributes">
            <attribute name="readonly">False</attribute>
        </xpath>
    </field>
</record>

But it does not work as intended. It restrict everyone without base.group_system from editing and I need to allow other users to edit this field in some cases (for example while creating new users). Or if it is possible - set this field to readonly only when user we are editing have "base.group_system" and we don't.

#EDIT Internal users should not be able to edit other users. Manager (user with group Access Rights - group_erp_manager) should be able to edit Internal users and other managers but not admins. Admin (user with group Settings - group_system) should have access to edit everyone.


Solution

  • If by editing you mean stop the user from editing any field you really have a lot of cases, because you need to check for example:

    1. manager cannot create an admin user
    2. manger cannot make him self admin but can create other manager or normal users
    

    I created a application for this but really it's not with now it's in work.

    Okay i'm going to try a simple solution that allow a manager to edit any user but stop him with error message if he is trying to edit a admin.

    @api.multi
    def check_editing_previlage(self):
        """ check if users is allowed to edit this record."""
        # admin can do what ever he wants
        if self.env.user.has_group('base.group_system'):
            return True
        if self.env.user.has_group('base.group_erp_manager'):
            # 1. admin can create a user
            if isinstance(self.id, models.NewId):
                return True
            # 2. he is not allowed to edit and admin
            if self.has_group('base.group_system'):
                return False
            # 3. he is allowed to edit this users
            return True
    
        # other user are not allowed to edit any user
        return False
    
    
    
    @api.mutli
    def write(self, vals):
        for rec in self:
            if not rec.check_editing_previlage():
                # show a nice error that tells the user that he is not allowed to edit 
                # this user
                raise exceptions.ValidationError(_('''You are not allowed to edit user %s contact your manager
                                                   if you think that is an error.
                                                   ''') % rec.name)
        # continute the editing otherwise 
        return super(ClassName, self).write(vals)
    

    The problem with this solution is that a manager can make him self or another use an admin . In order for you to stop this you need to check what are the groups that are added and removed and raise an exception if a non admin user is trying to add or remove an admin previlage. you can post another question and specify the what Odoo version you are using.