权限等级
- 第一级是access rule,即表级(对象)权限,控制用户组对某个对象是否有创建、读取、修改、删除的权限,一般是用security/ir.model.access.csv文件来管理。
- 第二级是行级权限,控制用户组对表中数据行的访问权限,可以写在views/views.xml文件中。
- 第三级是字段级权限,一个对象或表上的某些字段的访问权限。
- 第四级是菜单级权限,不属于指定菜单所包含组的用户看不到该菜单。
创建模块
版本:odoo8
(python 2.7环境)
python ./odoo.py scaffold academy ./openerp/addons_test切换用户到开发者模式
右上角用户,点击关于,页面右上角“激活开发者模式”
更新模块列表
Settings->Modules->Update Modules List
安装模块
Settings->右上角搜索模块名
一、表级权限
新建modelacademy/models.py
class Teachers(models.Model): _name = 'academy.teachers' name = fields.Char('Teacher Name') biography = fields.Html() user_id = fields.Many2one('res.users', string="User", ondelete='cascade', required="true") class Courses(models.Model): _name = 'academy.courses' name = fields.Char() teacher_id = fields.Many2one('academy.teachers', string="Teacher") course_ids = fields.One2many('academy.courses', 'teacher_id', string="Courses")
给两个表添加基本的视图以及新建两个菜单
academy/views.xml
<openerp> <data> <record id="action_academy_teachers" model="ir.actions.act_window"> <field name="name">Academy teachers</field> <field name="res_model">academy.teachers</field> </record> <record id="academy_teacher_tree" model="ir.ui.view"> <field name="name">Academy teachers: tree</field> <field name="model">academy.teachers</field> <field name="arch" type="xml"> <tree> <field name="user_id"/> </tree> </field> </record> <record id="academy_teacher_form" model="ir.ui.view"> <field name="name">Academy teachers: form</field> <field name="model">academy.teachers</field> <field name="arch" type="xml"> <form> <sheet> <label for="user_id"/> <field name="user_id"/> <label for="biography"/> <field name="biography"/> </sheet> </form> </field> </record> <record id="action_academy_courses" model="ir.actions.act_window"> <field name="name">Academy courses</field> <field name="res_model">academy.courses</field> </record> <record id="academy_course_search" model="ir.ui.view"> <field name="name">Academy courses: search</field> <field name="model">academy.courses</field> <field name="arch" type="xml"> <search> <field name="name"/> <field name="teacher_id"/> </search> </field> </record> <record id="academy_course_list" model="ir.ui.view"> <field name="name">Academy courses: list</field> <field name="model">academy.courses</field> <field name="arch" type="xml"> <tree string="Courses"> <field name="name"/> <field name="teacher_id"/> </tree> </field> </record> <record id="academy_course_form" model="ir.ui.view"> <field name="name">Academy courses: form</field> <field name="model">academy.courses</field> <field name="arch" type="xml"> <form> <sheet> <label for="name"/> <field name="name"/> <label for="teacher_id"/> <field name="teacher_id"/> </sheet> <div class="oe_chatter"> <field name="message_follower_ids" widget="mail_followers"/> <field name="message_ids" widget="mail_thread"/> </div> </form> </field> </record> <menuitem sequence="0" id="menu_academy" name="Academy"/> <menuitem id="menu_academy_content" parent="menu_academy" name="Academy Content"/> <menuitem id="menu_academy_content_teachers" parent="menu_academy_content" action="action_academy_teachers"/> <menuitem id="menu_academy_content_courses" parent="menu_academy_content" action="action_academy_courses"/> </data> </openerp>
表级的权限控制文件在academy/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_academy_teachers,access_academy_teachers,model_academy_teachers,,1,0,0,0
如上的group_id没有加,就是对所有组公开了teacher表的读取权限,重启odoo并升级(admin),切换用户(非admin),可看到效果页面:
可以看到该用户对teacher仅有读取权,但添加、修改、删除不能操作。
二、行级权限
比如访问“客户”对象,业务员只能对自己创建的客户有访问权限,而经理可以访问其管辖的业务员所有的“客户”对象。在ir.rule模型中定义规则,存储在public.ir_rule表格里面。
新建规则文件security/academy_record_rules.xml,并注册到__openerp__.py的data的属性中。
security/academy_record_rules.xml
<?xml version="1.0" encoding="utf-8"?> <openerp> <data noupdate="1"> <record id="academy_user_rule" model="ir.rule"> <field name="name">Academy only for owner</field> <field name="model_id" ref="model_academy_teachers"/> <field name="domain_force"> [('create_uid','=',user.id)] </field> <!--<field name="groups" eval="[(4,ref('base.group_user'))]"/>--> </record> </data> </openerp>name 规则名称
model_id 对应的模型
global 是否是全局
domain_force 过滤条件,在创建id等于当前用户id时,显示该条记录
groups 属于哪个组base.group_user是所有组,可以不写
security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_academy_teachers,access_academy_teachers,model_academy_teachers,,1,1,1,1 access_academy_courses,access_academy_courses,model_academy_courses,,1,0,0,0
先开放teacher模块对所有组的所有权限,重启Odoo并升级academy,登陆非admin用户,可以看到teacher可新建,并只能看见自己创建的数据。
注释
(4,ID)添加主从链接关系到id=ID的对象。
(3,ID)去除和id=ID的对象主从链接关系,但是不删除这个对象
(2,ID) 去除和id=ID的对象主从链接关系,并且删除这个对象(调用unlink方法)
(5) 去除所有的链接关系,也就是循环所有的从数据且调用(3,ID)
(6,0,[IDs]) 用IDs里面的记录替换原来链接的记录,即先执行(5)再循环IDs执行(4,ID)
三、字段级权限
创建用户的权限组使用record记录,存储在res.groups里
security/academy_groups.xml
<?xml version="1.0" encoding="utf-8"?> <openerp> <data noupdate="1"> <record model="ir.module.category" id="module_category_academy_test"> <field name="name">academy test</field> </record> <record id="academy_teachers_group" model="res.groups"> <field name="name">Academy teachers group</field> <field name="comment">the comment of the group.</field> <field name="category_id" ref="module_category_academy_test"/> <!--<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>--> <!--<field name="users" eval="[(4, ref('base.user_root'))]"/>--> </record> <record id="academy_managers_group" model="res.groups"> <field name="name">Academy managers group</field> <field name="comment">the comment of the group.</field> <field name="category_id" ref="module_category_academy_test"/> </record> </data> </openerp>
首先定义了分组category,然后定义了两个组属于同一分组(也可以不写分组)。
注释
name 组名
comment 组的注释
category_id 所属于哪个模块
users 预定义属于该组的用户
implied_ids
在demo.xml中添加两条记录,创建两个用户
demo.xml
<record id="user_teacher_a" model="res.users"> <field name="name">teacherA</field> <field name="login">[email protected]</field> <field name="password">academy</field> </record> <record id="user_teacher_b" model="res.users"> <field name="name">teacherB</field> <field name="login">[email protected]</field> <field name="password">academy</field> </record> <record id="teacher_a" model="academy.teachers"> <field name="name">TeacherA</field> <field name="work_email">[email protected]</field> <field name="user_id" ref="academy.user_teacher_a"/> </record> <record id="teacher_b" model="academy.teachers"> <field name="name">TeacherB</field> <field name="work_email">[email protected]</field> <field name="user_id" ref="academy.user_teacher_b"/> </record>
登陆admin给teacherA添加到academy_teachers_group组,设置->用户 找到teacherA编辑,会看到权限多了分组,勾选Academy teachers group。
给字段添加组权限有两个地方
在视图中给field加groups属性
academy/views.xml
<record id="academy_teacher_tree" model="ir.ui.view"> <field name="name">Academy teachers: tree</field> <field name="model">academy.teachers</field> <field name="arch" type="xml"> <tree> <field name="user_id"/> <field name="name"/> <field name="biography" groups="academy.academy_teachers_group"/> <field name="show_group_teacher"/> </tree> </field> </record>或者在字段定义的地方加groups属性
academy/models.py
class Teachers(models.Model): _name = 'academy.teachers' name = fields.Char('Teacher Name') biography = fields.Html() user_id = fields.Many2one('res.users', string="User", ondelete='cascade', required="true") show_group_teacher = fields.Char('Show For Teacher', groups="academy.academy_teachers_group")
重启odoo并升级academy,可以登陆TeacherA和TeacherB查看效果。
四、菜单级权限
在菜单定义处加groups属性(或者groups_id)academy/views.xml
<menuitem id="menu_academy_content_courses" parent="menu_academy_content" action="action_academy_courses" groups="academy.academy_teachers_group"/>重启odoo并升级academy,可以登陆TeacherA和TeacherB查看效果。