在今年的情人節(2018.02.14)那天,我寫了一篇博客說即將要開一個坑,也就是你們在看的這個系列的教程。今天這個系列教程即將迎來它的最後一篇內容了,咱們將要來學習 Odoo 中權限相關的內容。git
在多用戶系統中,並非全部數據都是能夠開放給所有用戶的,因此在多用戶系統中,權限管理是很是重要的一環。一般咱們會根據業務和組織架構對用戶進行分組管理,也就是咱們常說的用戶組或角色組,而後再根據用戶組對用戶所能接觸到的數據內容進行控制。github
在 Odoo 的權限管理體系中,一樣也有用戶組這一律唸的存在,和其餘框架(如 Django)能夠說大同小異。回到咱們的 Todo 應用裏來,從一開始咱們就是用的超級管理員帳戶 admin
登陸和操做的,這在任何生產環境和測試環境裏都是不容許出現的,可是在前面的教程裏,咱們都沒有提到過帳戶和權限相關的內容,是爲了讓教程能一路走下來,因此咱們今天就來糾正這個錯誤。瀏覽器
在咱們的 Todo 應用中,假設有「用戶」和「管理員」兩個用戶組,普通用戶能夠建立、修改和刪除本身建立的待辦事項,而管理員除了擁有普通用戶的操做權限外,還能夠建立、修改和刪除分類數據。微信
如今咱們就來看看應該如何定義這兩個用戶組,和定義其餘數據同樣,咱們一樣須要在 xml 文件中定義用戶組數據,找到模塊下的 security
目錄,而後建立一個 todo_security.xml
文件,用於定義咱們的用戶組數據:架構
<?xml version="1.0" encoding="utf-8"?> <odoo> <data noupdate="0"> <record id="module_category_todo" model="ir.module.category"> <field name="name">待辦事項</field> </record> <record id="group_todo_user" model="res.groups"> <field name="name">用戶</field> <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> <field name="category_id" ref="todo.module_category_todo"/> <field name="users" eval="[(4, ref('base.user_root'))]"/> </record> <record id="group_todo_manager" model="res.groups"> <field name="name">管理員</field> <field name="implied_ids" eval="[(4, ref('base.group_user')), (4, ref('todo.group_todo_user'))]"/> <field name="category_id" ref="todo.module_category_todo"/> <field name="users" eval="[(4, ref('base.user_root'))]"/> </record> </data> </odoo>
這裏總共有 3 條記錄,分別是 Todo 模塊分類(ir.module.category
)和「用戶」及「管理員」兩個用戶組(res.groups
),重點來看看用戶組裏各個字段所表明的含義:框架
category_id
:該用戶組所屬的模塊分類implied_ids
:在當前用戶組下的用戶,同時加入該字段所指定的用戶組中users
:該字段所指定的用戶默認被加入到當前用戶組中在上面的記錄中,還有兩個引用(ref
),分別是 base.group_user
基礎用戶組和 base.user_root
管理員帳戶。dom
別忘了把 'security/todo_security.xml'
加入到 __manifest__.py
的 data
列表中,將它放在 # 'security/ir.model.access.csv'
這一行的上面,而後升級更新模塊以後打開設置菜單下的「用戶」菜單,打開管理員帳戶 Administrator
的表單視圖。學習
這時咱們能夠看到在「Application Accesses」下出現了咱們剛剛建立的「待辦事項」模塊分類,進入編輯模式後,能夠看到有「用戶」和「管理員」兩個選項測試
能夠發現超級管理員帳戶已經默認被分配到了待辦事項分類下的「管理員」組中了,這也和咱們前面說的 users
字段所表現的行爲是一致的,再返回列表,打開 Demo User
這個帳戶看看,是否是並無加入咱們建立的用戶組中的任何一個呢 :)ui
用戶組建立好了以後,事情遠遠尚未結束,由於我沒並無爲這兩個用戶組分配相關數據的操做權限。那若是咱們如今建立一個新的用戶,而且加入到任意的用戶組中,而後登陸訪問系統,會發生什麼呢?實踐出真知,咱們來建立一個 test
用戶而且分配到「用戶」組中,而後登陸看看會發生什麼
注:修改新建立的帳戶密碼,打開 Action 下拉菜單,點擊 Change Password 便可修改
打開隱身窗口或者在另外一個瀏覽器上登陸,你會看到頁面上什麼都沒有,爲何會這樣?
不要感到迷惑,這確實是由於咱們沒有給用戶組分配任何數據的操做權限致使的,用戶沒有對數據的讀寫權限,天然就沒法查看到相關的內容了。在 Odoo 中給用戶組分配權限,是以模型爲單位的,也就是說只有某個用戶組被分配了對應模型的權限以後,該用戶組內的用戶才能操做對應模型下的數據。用戶組權限的定義是以 .csv
格式文件存儲的,在建立模塊時默認已經生成了一個權限記錄文件 security/ir.model.access.csv
,打開它咱們能夠看到裏面有一條記錄,這是在建立模塊時自動生成的,能夠看到裏面有 8 個字段,分別表明的含義以下
id
:這條權限記錄的 id,能夠類比爲 xml_id
name
:權限記錄的名稱model_id:id
:要配置權限的模型的外部 ID (以 model_
開頭)group_id:id
:應用此條權限配置的用戶組的 id,若爲空則默認對全部用戶組生效perm_read
:讀取記錄的權限,1 爲擁有該權限,0 爲不分配該權限perm_write
:編輯更新記錄的權限,取值同上perm_create
:建立新記錄的權限,取值同上perm_unlink
:刪除記錄的權限,取值同上若是不理解也不要緊,咱們先來給「用戶」組添加對模型 todo.task
的操做權限,經過實例會更容易理解:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_todo_task_user,todo.task.user,model_todo_task,group_todo_user,1,1,1,1
咱們在這裏爲「用戶」組(group_todo_user
)添加了對 todo.task
待辦事項模型的讀寫建立和刪除四個操做的權限,而後打開 __manifest__.py
並將 # 'security/ir.model.access.csv'
這行的註釋取消掉,而後升級更新模塊,而後刷新剛剛登陸的 test
帳戶的界面,是否是能夠看到有數據了呢
終於不是空空如也的頁面了,但是有沒有以爲哪裏不對呢?是的,這個帳戶是新的帳戶,可是卻看到了超級管理員建立的數據,拋開這個問題無論先,這個咱們後面會再來解決。如今咱們要作的是建立一條新的記錄,看看能不能成功建立一條新的記錄
Oops! 在選擇分類的時候忽然彈出了個錯誤,這是怎麼回事呢,來仔細看看錯誤提示的內容
對不起,你沒有權限訪問該文檔。若是你認爲這是一個錯誤,請聯繫系統管理員。
(文檔模型:todo.category)
看起來問題並不在咱們的待辦事項(todo.task
)模型上,而是在分類模型上,咱們剛剛分配用戶組權限時只分配了待辦事項模型的權限,因此當用戶視圖讀取分類模型的數據時,就會提示沒有權限訪問。解決這個問題一樣很簡單,只須要加上分類模型的權限便可
access_todo_category_user,todo.category.user,model_todo_category,group_todo_user,1,0,0,0
將上面的權限定義加到 ir.model.access.csv
文件的行末,而後升級更新模塊後再次建立,此次終於成功建立起來了。
對權限分配這部份內容的認識有沒有比剛開始更開始要清晰一些了呢?那咱們這裏就留一個小做業吧:
爲用戶組「管理員」添加權限,容許該用戶組下的用戶對分類模型進行管理,包括建立、刪除、更新和讀取
若是不知道寫得是否正確,能夠參考源碼中的個人寫法。
用戶組權限是粒度較粗的權限控制方式,它只能針對於某一個模型的所有記錄應用相關權限配置,可是某些時候,咱們會須要粒度更細的權限控制方式。一個現成的例子就是上一節中,咱們用新建的測試帳戶登陸後,能夠看到超級管理員所建立的待辦事項的記錄,這是不合理的,一個普通的用戶,應該只能看到和操做他所建立的記錄。
值得慶幸的是,Odoo 爲咱們提供了基於記錄集的權限控制方式,咱們能夠很輕鬆地根據業務需求編寫相應的規則,將權限控制的粒度精細到具體的記錄上。爲了體現記錄集權限的用法,咱們將假設在咱們的 Todo 應用中,普通用戶只能讀取和操做由本身建立的待辦事項,而管理員則能夠查看和刪除(但不能修改)全部用戶建立的待辦事項。
一般和權限相關的內容,咱們都會在模塊的 security
目錄下進行定義,記錄集規則的定義天然也不例外。咱們建立一個 ir_rule.xml
的文件,而後添加記錄集規則的定義
<?xml version="1.0" encoding="utf-8"?> <odoo> <data noupdate="1"> <record id="rule_todo_task_user" model="ir.rule"> <field name="name">待辦事項規則 - 用戶</field> <field name="model_id" ref="model_todo_task"/> <field name="domain_force">[('create_uid', '=', user.id)]</field> <field name="groups" eval="[(4, ref('todo.group_todo_user'))]"/> <field name="perm_read" eval="True"/> <field name="perm_write" eval="True"/> <field name="perm_create" eval="True"/> <field name="perm_unlink" eval="True"/> </record> <record id="rule_todo_task_manager" model="ir.rule"> <field name="name">待辦事項規則 - 管理員</field> <field name="model_id" ref="model_todo_task"/> <field name="domain_force">[('create_uid', '!=', user.id)]</field> <field name="groups" eval="[(4, ref('todo.group_todo_manager'))]"/> <field name="perm_read" eval="True"/> <field name="perm_write" eval="False"/> <field name="perm_create" eval="True"/> <field name="perm_unlink" eval="True"/> </record> </data> </odoo>
以後要作的事固然就是把 'security/ir_rule.xml'
添加到 __manifest__.py
的 data
中啦,再來就是升級更新模塊,如今刷新瀏覽器,應該看不到其餘用戶建立的待辦事項記錄了,完美達成目的~如今讓咱們回到管理員帳戶所在的瀏覽器,而後建立一個新的帳戶,並添加到「管理員」組內,接着再新開一個隱身窗口登陸這個新建立的管理員帳戶,咱們能夠看到和預期的結果同樣,管理員能夠看到所有用戶建立的待辦事項記錄,隨便點擊一條記錄並編輯,修改任意內容後保存,這時候你會發現彈出了一個錯誤警告
這個錯誤提示咱們當前用戶沒有權限修改這一條記錄,就如咱們前面的假設同樣,管理員不能修改其餘用戶建立的記錄,剩下的建立和刪除,你們能夠隨意測試。
看完了效果以後,又到了解釋說明的時間了,咱們先來看到定義的規則裏最後四個屬性字段,是否是很熟悉呢?沒錯,這就是咱們在定義用戶組權限時所看到的表示讀寫建立和刪除這四個操做的屬性,在記錄集權限的定義裏,他們的含義是同樣的,只不過屬性值從 0 和 1 變成了 True 和 False,而後咱們再來看看另外幾個字段:
model_id
:要應用該規則的模型的外部 IDdomain_force
:過濾條件,符合該條件的記錄都將按照所定義權限進行檢查,其中變量 user
表示當前用戶的實例對象,能夠直接使用groups
:應用該規則的用戶組,若是不指定則默認對所有用戶應用該規則目前爲止,一切看起來都很不錯,不過還有點美中不足。咱們再次打開測試帳戶所在的瀏覽器窗口,咱們前面留了一個小做業,分類只容許管理員進行管理,那麼咱們天然不但願普通用戶看到多餘的菜單內容了,因此某些時候用戶雖然對某些數據具備可讀的權限,可是未必會想要開放對應的菜單入口給這些用戶。而咱們要根據用戶組來對菜單的可見性進行處理,其實也很簡單,只須要在對應的菜單項上添加一個 groups
屬性便可,裏面的值能夠是逗號分隔的多個用戶組的外部 ID,以「分類」菜單爲例
<!-- views/menus.xml --> <menuitem action="action_todo_category" id="submenu_todo_category" name="分類" parent="menu_todo_submenu" sequence="8" groups="todo.group_todo_manager"/>
就這麼簡單,更新模塊以後刷新瀏覽器看看,「分類」菜單是否是已經被隱藏起來了呢,而管理員帳戶依然能夠看到該菜單。除了菜單外,在視圖的字段上也能夠經過添加屬性 groups
達到針對不一樣的用戶組隱藏相關字段的目的。
以上就是這篇教程的所有內容了,老規矩,代碼都在 GitHub 倉庫「Odoo-Tutorial-Demo」中。
雖然說這是「Odoo 基礎教程系列」的最後一篇內容了,可是這不意味着以後不會再寫 Odoo 相關的內容了,感謝你們一直以來的支持,雖然很小衆,可是也有很多小夥伴給予了一些正面的鼓勵,雖然更新速度很慢很慢,可是這個系列終於仍是完成啦!自我感受仍是有不少寫得很差的地方,但願之後能夠寫得更好~
若是你們有什麼問題想要獲得解答,能夠加入羣裏,和其餘小夥伴一塊兒交流或者提問,添加下面這個微信,備註 Odoo 加羣,經過後將會拉入羣裏的 :)