在Odoo中,使用使用者組(res.groups)來管理許可權,一個特殊的使用者組是 員工/員工(base.group_user) 組,所有的使用者都屬於這個組,這個組裡包含一些基本的許可權。
四種許可權級別(粒度越來越細):
1.選單/物件級別
設定哪些人可以訪問哪些選單/物件,物件的訪問許可權包括建立、讀、寫、刪除。
2.記錄級別
設定哪些人可以訪問哪些記錄,也就是設定表的查詢條件。
3.欄位級別
設定表中的欄位的訪問許可權。
4.工作流級別(很少用到)
在工作流的每一步遷移中,設定哪些角色允許觸發本遷移
下面示例使用的是account模組中的程式碼,所以大家有什麼問題可以去odoo原始碼查詢。
關於許可權的檔案一般在security資料夾中,
xxx_security.xml檔案定義使用者組和使用者組對選單的訪問許可權
ir.model.access.csv定義使用者組對物件的許可權矩陣
選單/物件級別
使用者組
首先建立一個組分類(表示很多組屬於一個分類):
<record id="base.module_category_accounting_and_finance" model="ir.module.category">
<field name="name">module_category_accounting_and_finance</field>
<field name="sequence">57</field>
</record>
再建立一個使用者組:
<record id="group_account_invoice" model="res.groups">
<!-- 組的名字,如:員工 -->
<field name="name">Billing</field>
<!-- 此組屬於的組分類 -->
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
<!-- 繼承的組,也就是說這個組也擁有這些繼承組的許可權 -->
<field name="implied_ids" eval="[(4, ref(`base.group_user`))]"/>
</record>
修改這個組的一些內容,如:給這組加上一個使用者:
<record id="group_account_invoice" model="res.groups">
<!-- 給這個組新增admin使用者 -->
<field name="users" eval="[(4, ref(`base.user_root`))]"/>
</record>
下面說一下eval語法:
(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)在迴圈執行(4, ID))
使用者組對model的許可權控制(也就是物件的訪問許可權)
模組下 security 目錄下的檔案:ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_product_product_account_user,product.product.account.user,product.model_product_product,group_account_user,1,0,0,0
access_product_product_account_manager,product.product.account.manager,product.model_product_product,group_account_manager,1,1,1,1
access_product_template_account_manager,product.template.account.manager,product.model_product_template,group_account_manager,1,1,1,1
access_product_price_history_account_manager,prices.history.account.manager,product.model_product_price_history,group_account_manager,1,1,1,1
access_account_payment_term,account.payment.term,model_account_payment_term,account.group_account_`user,1,0,0,0
id:可以隨便取,但是在一個模組中是唯一的,一般取名為 access_模型名_特定使用者組名(用下劃線連起來)
name: 可以隨便取,一般命名沿用模型名用“.”連線加 使用者組名
model:id: 要做許可權控制的model,格式寫法是 模組名.model_模組名(中間的‘.’換成‘_’),如果model在此模組中,可以省略模組名,如product.model_product_product
group:id:組的id,不是本模組的組,要在前面加上模組名,如:account.group_account_user
perm_read,perm_write,perm_create,perm_unlink:這些就是具體的許可權:讀寫增刪,1 有許可權,0 無許可權
選單的許可權控制
第一種寫法(所有的記錄,都可以用這種方法新增及修改,如果id是一樣的話就是修改這條記錄,如果沒有這個id就是新增該記錄)
<record id="menu_finance" model="ir.ui.menu">
<field name="name">Invoicing</field>
<field name="web_icon">account,static/description/icon.png</field>
<field name="sequence">40</field>
<field name="groups_id" eval="[(6, 0, [ref(`account.group_account_user`), ref(`account.group_account_manager`), ref(`account.group_account_invoice`)])]"/>
</record>
第二種寫法(簡潔寫法)
<menuitem name="Invoicing"
id="menu_finance"
groups="group_account_user,group_account_manager,group_account_invoice"
web_icon="account,static/description/icon.png"
sequence="40"/>
上面的2個xml表示menu_finance這個選單隻能被group_account_user,group_account_manager,group_account_invoice 三個使用者組訪問
如果有上級選單,加parent屬性,如果上級選單不在本模組中,需要加模組名如:account.menu_finance:
<menuitem id="menu_finance_reports" name="Reports" parent="menu_finance" sequence="5" groups="group_account_invoice"/>
記錄級別的許可權控制
記錄的許可權放在”ir.rule”model中,所有我們新增或修改ir_rule表中的記錄,就可以控制記錄的許可權
<record id="account_move_comp_rule" model="ir.rule">
<!-- 規則名稱 -->
<field name="name">Account Entry</field>
<!-- 對應模型 -->
<field name="model_id" ref="model_account_move"/>
<!-- 是否全域性 -->
<field name="global" eval="True"/>
<!-- 過濾條件 其中user表示當前登入使用者物件 -->
<field name="domain_force">[`|`,(`company_id`,`=`,False),(`company_id`,`child_of`,[user.company_id.id])]</field>
<!-- 讀寫增刪許可權(針對過濾後的記錄) -->
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
domain_force(也就是domain表示式的寫法)寫法請看我的另一篇部落格domain的寫法及運用。
欄位級別的許可權控制
給欄位上新增使用者組,表示只有這些組的使用者在這個檢視中才能訪問和操作這個欄位,如:
<record id="view_invoice_line_tree" model="ir.ui.view">
<field name="name">account.invoice.line.tree</field>
<field name="model">account.invoice.line</field>
<field name="arch" type="xml">
<tree string="Invoice Line">
<field name="name"/>
<field name="account_id" groups="account.group_account_user"/>
<field name="quantity"/>
<field name="uom_id" groups="product.group_uom,account.group_account_user"/>
<field name="price_unit"/>
<field name="discount" groups="base.group_no_one"/>
<field name="price_subtotal"/>
<field name="currency_id" invisible="1"/>
</tree>
</field>
</record>
上面xml表示在這個tree檢視(這裡注意,這個許可權只針對這個tree檢視)上,account_id,uom_id,discount這3個欄位只有對應的使用者組中的使用者才能看到。
如果你想在這個model的所有檢視中都有這個許可權控制的話,要在這個欄位定義的時候,就要指定groups,多個使用者組用”,”分隔,如:
gengo_private_key = fields.Text(string="Gengo Private Key", copy=False, groups="base.group_system,base.group_user")
許可權控制到這裡就結束了,如果有什麼錯誤的地方,歡迎大家指出。