Reputation: 10189
As always, problems with rules. I thought I had finally understood them, but not.
I am looking the behaviour of model accesses and rules in the module hr_attendance
of Odoo 11.
THE CODE
They create three groups:
group_hr_attendance
(Manual Attendance).group_hr_attendance_user
(Officer): belonging to this group implies belonging to group_hr_attendance
.group_hr_attendance_manager
(Manager): belonging to this group implies belonging to group_hr_attendance_user
.They give the following model accesses to the groups:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_attendance_user,hr.attendance.user,model_hr_attendance,hr_attendance.group_hr_attendance_user,1,1,1,1
access_hr_attendance_system_user,hr.attendance.system.user,model_hr_attendance,base.group_user,1,1,1,0
They are setting accesses to Officer and the basic group Employee.
And they apply the following rules:
<record id="hr_attendance_rule_attendance_manager" model="ir.rule">
<field name="name">attendance officer: full access</field>
<field name="model_id" ref="model_hr_attendance"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups" eval="[(4,ref('hr_attendance.group_hr_attendance_user'))]"/>
</record>
<record id="hr_attendance_rule_attendance_employee" model="ir.rule">
<field name="name">user: modify own attendance only</field>
<field name="model_id" ref="model_hr_attendance"/>
<field name="domain_force">[('employee_id.user_id','=',user.id)]</field>
<field name="perm_read" eval="0"/>
<field name="perm_write" eval="1"/>
<field name="perm_create" eval="1"/>
<field name="perm_unlink" eval="0"/>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
THE BEHAVIOUR
If I log in with a basic user who belongs to the Manual Attendance group, I can see attendances whose employee's users are not mine, and if I open and try to modify them, I get a security error: (Document type: Attendance, Operation: write).
HOW I THINK THIS CASE WORKED
My user belong to Manual Attendance group: it does not have model accesses so I have the CRUD 0 0 0 0 (I cannot create, read, update or delete any record of the hr_attendance
model). But my user (as everyone) also belongs to Employee group, so I also have the CRUD 1 1 1 0. As model accesses are additive, I can create, read and update any record of hr_attendance
model, but not delete.
After that, the rules are restricting the CRUD. The non-global rule hr_attendance_rule_attendance_employee
(user: modify own attendance only) is affecting to my user: supposedly, the records which match the domain will be accessible for my group. The other ones will not. So I will not be able to interact with attendances whose employee's user is not mine. And I have two doubts here:
Why the rule has a 0 in read? Isn't that destroying my read permission given by the model accesses? I thought global or non-global rules were restrictive against model accesses.
And why I can read records whose employee's user is not mine? They do not match the rule so I should not be able to see them, shouldn't I?
Upvotes: 2
Views: 672
Reputation: 364
I think you misunderstanding the record rule perm_*
, are used to make the record rule applicable or the opposite.
A: The read value set to 0 to make sure this rule is not evaluated when the user make a read request. And you are not destroying your read permission given by the model access, if the read value was set to 1, you can say that you are narrowing the model access permission, from the whole model to the records those only passed the forced domain.
Q: And why I can read records whose employee's user is not mine? They does not match the rule so I should not be able to see them, shouldn't I?
A: **According to your model access, both groups have read access, and there are no record rules limiting read access.
The first rule hr_attendance_rule_attendance_manager
, is evaluated on the read
, write
, create
and unlink
access to the group hr_attendance.group_hr_attendance_user
. (No explicit evaluation peams provided, by default set to 1)
The second rule hr_attendance_rule_attendance_employee
is evaluated on the write
and create
access only (perm_write=1 and perm_create=1), and not evaluated on the read
and unlink
access (perm_read=0 and perm_unlink=0).
You should be able to unlink also :). To get the result that you want, you need to set the perm_read
to 1, and to force the domain on the unlink access you need to set the perm_unlink
also to 1.
you may use separate rules for each access request (read, write, create and unlink) when you have complex access conditions.
I hope this helps
Upvotes: 4