文章目录
odoo权限的层级划分
根据对象不同主要分为四个层级:
- 模型或对象(表级)访问权限:对某个对象是否有’创建,读取,修改,删除’的权限,可以简单理解为表对象
- 记录规则权限(可以理解为表的行权限管理):对模型表中的数据的访问权限,比如访问“客户”对象表,业务员只能对自己的客户有访问权限,而经理可以访问其管辖的业务员所有的“客户”对象
- 字段级权限(一个对象或表上的某些字段的访问权限):一个对象或表上的某些字段的访问权限,比如产品的成本字段只有经理有读权限
'name':fields.char('Name',size=128,required=True,select=True,write=['base.group_admin'] read=['base.group_admin']) # 定义name字段只能超级用户组可进行读写
- 菜单权限:不属于指定菜单所包含组的用户看不到该菜单,不安全,只是隐藏菜单,若知道菜单ID,仍然可以通过指定URL访问
- 工作流级别:在工作流的状态迁移中,设置哪些组允许触发状态迁移
模型(表)级访问权限管理
- 权限管理核心是权限组,每个权限组,可以设置权限组的访问权限(perm_create、perm_read、perm_write、perm_unlink),在ir.model.access.csv 文件设置权限。
- 访问权限是累加的,用户的访问权限是他们通过其所有组获得的访问权限的联合。
- 对模型的权限设置一般是在security/ir.model.access.csv文件中进行配置
如上的group_id没有加,就是对所有组公开了该表的相关权限第一行是表头,表示分别需要填入的值 即 id,name,模型,用户组,最后四个为读,写,创建,删除权限 id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
记录规则权限
在security文件夹下创建“模块名_security.xml”的文件中编写
1)创建用户
<record id="user_v" model="res.users">
<field name="login">用户名</field>
<field name="password">密码</field>
<field name="partner_id" ref="base.partner_admin"/>
<field name="groups_id" eval="[(6,0,[])]"/>
<field name="signature"><![CDATA[<span>-- <br/>MR_V</span>]]></field>
</record>
2)新建权限组(用户组)
<!--创建一个组分类-->
<record id="module_access_odoo_hgs_huaguoxian" model="ir.module.category">
<field name="name">鲜果花模块设置</field>
<field name="description">测试权限管理</field>
<field name="sequence">1000</field>
</record>
<!--创建组-->
<record id="group_huaguoxian_user" model="res.groups">
<field name="name">鲜果花权限组</field>
<field name="category_id" ref="bim5d."/>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]" />
<field name="comment">the user will have access to his own data</field>
</record>
<record id="group_huaguoxian_user2" model="res.groups">
<field name="name">鲜果花权限组2</field>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
<field name="category_id" ref="odoo_hgs_huaguoxian.module_access_odoo_hgs_huaguoxian"/>
<field name="comment">用户可以访问自己的数据</field>
</record>
- name:用户组名,自定义的
- comment:用户组的注释
- category_id 用户组所属的模块名
- implied_ids 基于哪个用户组,这个层级关系 是最基础的用户名,最初是基于这个,后面一层一层递增,像上面 base.group_hr_user 定义时就是基于最基础
- users 预设用户属于这个用户组
3)创建记录规则( record rule )
<record model="ir.rule" id="hgs_huaguoxian_rule">
<field name="name">鲜果花退货单记录规则</field>
<field name="model_id" search="[('model','=','huaguoxian.delivery_return_order')]" model="ir.model"/>
<field name="groups" eval="[(4, ref('odoo_hgs_huaguoxian.group_huaguoxian_user'))]"/>
<field name="global" eval="True"/>
<field name="domain_force">[('return_status','=','2')]</field>
</record>
<record model="ir.rule" id="payment_notice_see_all">
<field name="name">All Payment Notice</field>
<field name="model_id" ref="model_payment_notice"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups" eval="[(4, ref('account.group_account_user'))]"/>
<field name="perm_read" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>
- record rule 记录是 ir.rule 模型, 存在public.ir_rule 表格中
- model_id 作用于哪个模型,值为 model_模型名
- domain_force 对该模型中所有记录进行某种过滤操作,常用的 [‘|’,(‘user_id’,‘=’,user.id),(‘user_id’,‘=’,False)] 表示是自己的单
- user_id是记录的字段,这个看实际情况改变, user.id 代表当前登录用户的id
[(1,‘=’,1)] 表示所有的单 - noupdate 值为1 表示升级模块不会更新本数据
- base.group_user 是人力资源 / 雇员
- perm_read 这些后面,是对 前面模型权限组设定的覆盖
字段权限控制
- 在视图的xml文件中
其实无论使用implied_ids还是users都是为了给新建的用户组填入默认用户,但这并不是一定要设置的。# 在网页展示的视图中,只有mrp_group_manager的用户才能看到name字段 <field name="name" groups="mrp.mrp_group_manager"/>
- 在字段定义的地方加groups属性
show_group_teacher = fields.Char('Show For Teacher', groups="academy.academy_teachers_group")
菜单级权限管理
在菜单定义处加groups属性(或者groups_id)
<menuitem id="menu_academy_content_courses" parent="menu_academy_content"
action="action_academy_courses" groups="academy.academy_teachers_group"/>
工作流权限管理
在py文件里,做限制。
两种思路:
- 在/security/ir.model.access.csv文件里将模型的权限将所有模型的perm_read,perm_create,perm_write,perm_unlink都设置为1,此时,所有组所有角色都有最高权限,再在view中用domain将菜单,对象,记录或者字段隐藏起来,只展示给部分的组
- 把perm_read,perm_create,perm_write,perm_unlink都设置为0,此时菜单、对象、记录或字段对所有组都是不可访问的。再在前端的组里不断把对象记录字段的权限加上。
两种思路都可以实现对权限的管理。思路一可以完全靠后端的代码定义达到目的。思路二可以仅通过前端的权限添加达到权限管理的目的。
实际情况可能会方法一和方法二结合。对不敏感的模型开放较多权限,后续开发中有需求再在view中设置domain,缩小权限。对较敏感的模型先不开放权限,再通过前端不断对特别的组添加权限。
隐藏的常用技巧
- 直接隐藏
<group name="owner" position="attributes"> <attribute name="invisible">True</attribute> </group>
- 满足某些条件的隐藏
<xpath expr="//field[@name='parent_id']" position='attributes'> <attribute name="attrs">{'invisible': [('passenger','=', True)]}</attribute> </xpath> <group col="4" string='旅客信息' attrs="{'invisible': [('supplier','=', True)]}"></group>
- 通过组来隐藏
<xpath expr="//field[@name='type']" position="attributes"> <attribute name="groups">base.group_no_one</attribute> </xpath>
- 菜单的隐藏
<record model="ir.ui.menu" id="crm.menu_crm_opportunities"> <field eval="[(6,0, [ref('base.group_no_one'),])]" name="groups_id"/> </record>
Eval
many2many
(0,0,{values}) 根据values里面的信息新建一个记录。
(1,ID,{values})更新id=ID的记录(写入values里面的数据)
(2,ID) 删除id=ID的数据(调用unlink方法,删除数据以及整个主从数据链接关系)
(3,ID) 切断主从数据的链接关系但是不删除这个数据
(4,ID) 为id=ID的数据添加主从链接关系。
(5) 删除所有的从数据的链接关系就是向所有的从数据调用(3,ID)
(6,0,[IDs]) 用IDs里面的记录替换原来的记录(就是先执行(5)再执行循环IDs执行(4,ID))
例子[(6, 0, [8, 5, 6, 4])] 设置 many2many to ids [8, 5, 6, 4]
one2many
(0, 0,{ values })根据values里面的信息新建一个记录。
(1,ID,{values}) 更新id=ID的记录(对id=ID的执行write 写入values里面的数据)
(2,ID) 删除id=ID的数据(调用unlink方法,删除数据以及整个主从数据链接关系)
例子:
[(0,0,{'field_name':field_value_record1,...}),(0,0,{'field_name':field_value_record})]
many2one的字段比较简单,直接填入已经存在的数据的id或者填入False删除原来的记录。
具体的详细信息可在Security in Odoo 中查看